I am implementing a small programming language. Here is the codebase. The program is built with ocamlbuild. I added a parser using menhir. When I compile and run the program, I got the following message.
❱ ./main.byte
Fatal error: exception Parser.MenhirBasics.Error
I am trying to find more details by passing the explain to the _tag file
true: color(always), explain
but there doesn't seem to be any difference. How to I make menhir to generate a logging file through ocamlbuild? or other ways to debug?
This is syntax error raised by the parser generated by menhir.
Your build system is irrelevant (nevertheless, you should use dune for a new project and not ocamlbuild).
Similarly, the --explain flag of menhir is only useful for generating conflict explanations when generating the parser. It doesn't add syntax error explanation to syntax error.
If you want to debug a menhir grammar, you can use menhir intepreter mode with menhir --interpret
menhir --interpret parser.mly
or list all possible syntax errors in your grammar with menhir --list-errors.
menhir --list-errors parser.mly
Both options should make the reason why `"hi." is a syntax error in your grammar relatively clear.
Related
I have a folder in which there are several .c and .h files, plus a message.xml file.
I don't want to scan the XML.
If I run cppcheck --enable=all *.* it finds and balks at the contents of the XML. Fine, I don't care about the XML, but still. I hate seeing ignorable errors/warnings.
Of course, cppcheck *.c --enable=all or cppcheck *.c *.h --enable=all ignores the XML.
But curiosity got to me and I found out about the "ignore" switch but its use is unclear. If I try
cppcheck *.* --enable=all -imessage.xml or various perturbations of that line, it still finds the XML and complains.
So what is the command syntax to ignore a specific file and to ignore, say, all *.xml or *.xls files?
I am a Cppcheck developer.
I guess it's a bug in Cppcheck. As far as I see in the help output you should be able to use -imessage.xml.
But I would suggest cppcheck . --enable=all. You don't normally compile headers directly and therefore you shouldn't analyze them directly neither. You get wrong handling of the include guard and you probably get false positives about unused struct members.. well there can be some wrong behavior and don't blame cppcheck.
I am using bison to generate a parser, however, when compiling the parser with the MSVC, I get an error which suggests that there is an error containing too many characters at the line after the last line in my bison file.
I have written a parser for a DSL language which used bison 2.7 for windows, I recently tried to use Conan to manage my dependencies which allowed me to get a newer version of win_bison (3.3.2). I examined the generated C++ source file and I found that the end of the file contains the following snippet of code.
#line 80 "Grammar.y" // lalr1.cc:1243
'_m4eof'
_m4eof
The last 2 lines prevent compilation and generates the error messages, these lines would not appear with win_bison 2.7.
How do I require a specific OCaml version when defining a jbuild specification?
For instance, suppose I have this file:
(jbuild_version 1)
(library
((name myjson)
(public_name myjson)
(synopsis "My version of json")
(libraries (yojson))))
But then I want to use Unix.unsafe_environment, which is not available on OCaml < 4.06. How do I add this constraint to the package, so that someone trying to compile it with an older OCaml will get a nice error message (instead of the more cryptic Error: Unbound value Unix.unsafe_environment)?
The jbuild specification does mention the existence of variable ocaml_version, but I couldn't find a simple example of how to use it.
There is currently no built-in way to make jbuilder print a gentle message when the ocaml version is incompatible with the library.
You should be able to use ocaml_version in a rule stanza that produces an empty .ml but fail when the version is wrong. But it should be better to ask for this feature wish.
You can solve that at the opam level (so that this package won't be installable) by adding this to myjson.opam:
available: [ ocaml-version >= "4.06.0" ]
(are you sure Unix.environment doesn't work for you? unsafe_environment comes with some special precautions to be used safely)
I have now spent days on this. WHAT am I doing wrong?!
I have a swig generated wrapper for a c++ library I'm interested in using (COIN-OR). So I wrote a c++ struct that has all the methods I need from coin, and I have written a Swig interface file awcbc.i. I then wrapped it with swig, and this generated a awcbc_wrapper.cxx file.
I have an extconf.rb file, which creates a makefile from this. I included the necessary libraries like this:
with_cflags("-x c++") do
abort 'missing cbc' unless find_library("Cbc", nil, "lib")
abort 'missing CbcModel.hpp' unless find_header("CbcModel.hpp", "include/coin")
abort 'missing awcbc.hpp' unless find_header("awcbc.hpp", "include")
end
"lib" is full of dylibs, one of which is Cbc. Similarly, CbcModel.hpp is one of the many headers in include/coin. The point of these is to include those directories, and thus all my dependencies into the search path. awcbc.hpp contains my struct.
When I run
$ ruby extconf.rb; make;
it creates a makefile and compiles it. I can then run irb, require awcbc, and it's all there and working.
However, when I try to put some of this into a rakefile (I've tried Jeweller, following the format set by a very similar library heroku-rglpk, or tried to use rake-compiler, as described in ruby-guides, I get
ERROR: Error installing ./pkg/awcbc-0.0.0.gem:
ERROR: Failed to build gem native extension.
/Users/*...*/.rbenv/versions/2.1.2/bin/ruby extconf.rb
checking for main() in -lCbc... no
missing cbc
*** extconf.rb failed ***
But it didn't fail when I called ruby extconf.rb manually!
This is one out of several nightmares in getting this fairly simple extension built.
What I'm shooting for, is a gem that I can put on ruby-gems which is basically the exact same thing as heroku-rglpk. I want it to check for Coin-Or, install if not there, wrap it, and gemify it. It's so frustrating that I can make the wrapper, and use it, but then I can't gemify it (and incidentally, this means I have NO IDEA how to include it in my rails app).
Bah. Can anyone help?
I am a bit frustrated and confused by the OCaml Batteries Included concept and the way most tutorials I could find proceed. Before I get to use "productivity" tools like GODI or replace invocations of ocamlc with ocamlfind batteries/ocamlc (which is, at this point, too magical for me) I was hoping to be able to simply use OCaml Batteries Included core set of libraries like any other library. To that end I downloaded the latest source from git (head hash: 9f94ecb) and did a make all. I noticed that I got three .cma libraries at ./_build/src/ together with 102 .cmi files in the same directory. So I assumed that compiling with the -I switch pointing to that directory and linking with one of the three .cma libraries found there would be enough without needing to "install" the Batteries or use the platform tools. To test that, I set out to produce an executable for the following simple program I found somewhere:
(* file euler001.ml *)
open BatEnum
open BatPervasives
let main () =
(1--999)
|> BatEnum.filter (fun i -> i mod 3 = 0 || i mod 5 == 0)
|> BatEnum.reduce (+)
|> BatInt.print stdout
let _ = main ()
I was able to compile it with:
ocamlc -c -I ../batteries-included/_build/src/ euler001.ml
but when I tried to link with:
ocamlc -o euler001 unix.cma nums.cma ../batteries-included/_build/src/batteries.cma euler001.cmo
I got:
File "_none_", line 1, characters 0-1:
Error: Error while linking ../batteries-included/_build/src/batteries.cma(BatBigarray):
The external function `caml_ba_reshape' is not available
The nums.cma and unix.cma I added at the command line because the linker complained about missing references to undefined global Big_int and (when that was added) to Unix. But after these two modules were added on the linker invocation I received the last message (on the missing external function 'caml_ba_reshape') which proved blocking for me. So I would like to ask:
how does one proceed in this particular case?
how does one proceed in the general case (i.e. when the linker complains about a missing external function)
is it viable to use Batteries Included in this fashion? Before I rely on platform tools I want to have the assurance that I can use the underlying artifacts (cma and cmi/mli files) with the standard OCaml compiler and linker if I run into problems.
caml_ba_reshape is, as you could guess from the name but I agree it's not obvious, a primitive of the Bigarray module. You should add bigarray.cma in your compilation command, before batteries.cma which depends on it.
There is a reason why it is advised to use ocamlfind, which is precisely used to abstract over those dependencies. I don't think you are supposed to use ocamlfind batteries/ocamlc, but rather ocamlfind ocamlc -package batteries. If you insist on using the compiler without such support, then indeed you have to compile manually -- I understand your frustration, but I hope you also understand that it is intrisic to any sufficiently sophisticated OCaml library, and that it comes only from your self-imposed constraints.
how does one proceed in the general case (i.e. when the linker complains about a missing external function
You have to know or guess where the primitive comes from. Looking at the META file provided by the library, which is used to inform ocamlfind of the dependencies, may help you. You can use the tool ocamlobjinfo to know which primitive a .cma provides, if you want to check your assumption. (Or better, use ocamlfind to spit the correct compile command, see below.)
is it viable to use Batteries Included in this fashion?
Compiling "by hand" is reasonable if you insist. Working only in the source repository, without installing the library, is not. It's easy to keep doing what you do after an install, just replace your -I ... by the chosen install path.
Before I rely on platform tools I want to have the assurance that I can use the underlying artifacts (cma and cmi/mli files) with the standard OCaml compiler and linker if I run into problems.
ocamlfind is not (only) a platform tool. It is the way to use third-party ocaml libraries, period. It should be a standard on any ocaml-using platform. That it does not come with INRIA's distribution is an historical detail.
You can ask ocamlfind to show you its invocation of the bare compilers:
% ocamlfind ocamlc -linkpkg -package batteries t.ml -o test -verbose
Effective set of compiler predicates:
pkg_unix,pkg_num.core,pkg_num,pkg_bigarray,pkg_str,pkg_batteries,autolink,byte
+ ocamlc.opt -o test -verbose -I /usr/local/lib/ocaml/3.12.1/batteries /usr/lib/ocaml/unix.cma /usr/lib/ocaml/nums.cma /usr/lib/ocaml/bigarray.cma /usr/lib/ocaml/str.cma /usr/local/lib/ocaml/3.12.1/batteries/batteries.cma t.ml
I don't want to throw stones at you. The landscape of OCaml tools, beside the minimal nutshell of what's provided by the source distribution, is quite sparse and lack a coherent point of entry. With time I've grown used to those tools and it's quite natural to use them, but I understand there is some cost of entry that we should try to lower.
PS: any advice on how to improve batteries documentation is warmly welcome. Patches to add things to the documentation or fix it are even better. batteries-devel#lists.forge.ocamlcore.org is the place to go.