對於OCaml,我是一個完整的新手。我最近纔開始使用該語言(大約2周前),但不幸的是,我的任務是編寫語法分析器(解析器+詞法分析器,其功能是接受或不是句子)使用Menhir。現在,我在網上找到了關於OCaml和Menhir的一些資料:OCaml + Menhir編譯/寫入
The Menhir手冊。
This webpage for some French University course.
上折騰的主頁在SourceForge短巨石教程。
由derdon在github上的Menhir示例。
A book on OCaml (with a few things about ocamllex+ocamlyacc
隨機ocamllex教程由SooHyoung哦。
以及Menhir源代碼附帶的例子。
(我不能把兩個以上的超鏈接,所以我不能直接將您鏈接到一些我提到這裏的網站。對不起!)
所以,你可以看到,我我一直在拼命尋找越來越多的材料來幫助我製作這個節目。不幸的是,我仍然無法理解許多概念,因此我遇到了許多困難。
對於初學者,我不知道如何正確編譯我的程序。我一直在使用以下命令:
ocamlbuild -use-menhir -menhir "menhir --external-tokens Tokens" main.native
我的程序分爲四個不同的文件:main.ml; lexer.mll; parser.mly; tokens.mly。 main.ml是從作爲參數給出的文件系統中的文件獲取輸入的部分。
let filename = Sys.argv.(1)
let() =
let inBuffer = open_in filename in
let lineBuffer = Lexing.from_channel inBuffer in
try
let acceptance = Parser.main Lexer.main lineBuffer in
match acceptance with
| true -> print_string "Accepted!\n"
| false -> print_string "Not accepted!\n"
with
| Lexer.Error msg -> Printf.fprintf stderr "%s%!\n" msg
| Parser.Error -> Printf.fprintf stderr "At offset %d: syntax error.\n%!" (Lexing.lexeme_start lineBuffer)
第二個文件是lexer.mll。
{
open Tokens
exception Error of string
}
rule main = parse
| [' ' '\t']+
{ main lexbuf }
| ['0'-'9']+ as integer
{ INT (int_of_string integer) }
| "True"
{ BOOL true }
| "False"
{ BOOL false }
| '+'
{ PLUS }
| '-'
{ MINUS }
| '*'
{ TIMES }
| '/'
{ DIVIDE }
| "def"
{ DEF }
| "int"
{ INTTYPE }
| ['A'-'Z' 'a'-'z' '_']['0'-'9' 'A'-'Z' 'a'-'z' '_']* as s
{ ID (s) }
| '('
{ LPAREN }
| ')'
{ RPAREN }
| '>'
{ LARGER }
| '<'
{ SMALLER }
| ">="
{ EQLARGER }
| "<="
{ EQSMALLER }
| "="
{ EQUAL }
| "!="
{ NOTEQUAL }
| '~'
{ NOT }
| "&&"
{ AND }
| "||"
{ OR }
| '('
{ LPAREN }
| ')'
{ RPAREN }
| "writeint"
{ WRITEINT }
| '\n'
{ EOL }
| eof
{ EOF }
| _
{ raise (Error (Printf.sprintf "At offset %d: unexpected character.\n" (Lexing.lexeme_start lexbuf))) }
第三個文件是parser.mly。
%start <bool> main
%%
main:
| WRITEINT INT { true }
第四個是tokens.mly
%token <string> ID
%token <int> INT
%token <bool> BOOL
%token EOF EOL DEF INTTYPE LPAREN RPAREN WRITEINT
%token PLUS MINUS TIMES DIVIDE
%token LARGER SMALLER EQLARGER EQSMALLER EQUAL NOTEQUAL
%token NOT AND OR
%left OR
%left AND
%nonassoc NOT
%nonassoc LARGER SMALLER EQLARGER EQSMALLER EQUAL NOTEQUAL
%left PLUS MINUS
%left TIMES DIVIDE
%nonassoc LPAREN
%nonassoc ATTRIB
%{
type token =
| ID of (string)
| INT
| BOOL
| DEF
| INTTYPE
| LPAREN
| RPAREN
| WRITEINT
| PLUS
| MINUS
| TIMES
| DIVIDE
| LARGER
| SMALLER
| EQLARGER
| EQSMALLER
| EQUAL
| NOTEQUAL
| NOT
| AND
| OR
| EOF
| EOL
%}
%%
現在,我知道有很多未使用的符號在這裏,但我打算在我的解析器使用它們。無論我對這些文件做了多少修改,編譯器都不停地在我的臉上。我試過了我能想到的一切,似乎沒有任何工作。什麼使ocamlbuild在大量的未綁定構造函數和未定義的開始符號的錯誤中爆炸?我應該使用什麼命令來正確編譯程序?我在哪裏可以找到有意義的材料來了解Menhir?
事實上,只有一個'mly'就簡單多了。我沒有在我的答案中提出這個解決方案,因爲我認爲@Lopson想要使用menhir的「單獨編譯解析單元」功能。 – Thomas 2012-03-28 08:00:12
感謝所有的幫助,各位,你不知道你的帖子對我來說有多寶貴!最後,事情開始變得有意義。 – 2012-03-28 11:19:19