2014-03-06 50 views
0

我在写一个解释器,使用ocamlyacc和ocamllex编译我的解析器和词法分析器。OCaml解释器:为什么我的解释器只在我的文件中只执行一行

我的问题是,我有一个文件卡列斯测试,包含在词法分析器中定义的两个命令:

print a 
print b 

但解释只是执行行只print a!我知道问题主要在解析器中,需要递归。我将它固定为这样(下面的代码),但它仍然不起作用。

%{ 
    open Path 
%} 

%token <int> INT 
%token <string> STRING 
%token EOL 
%token EOF 
%token GET_LINE 
%token PRINT 

%start main 
%type <Path.term> main 
%% 

main: 
    | expr EOL {$1} 
    | expr EOF {$1} 
; 


str: 
    | STRING { $1 } 
    ; 
intger: 
    | INT {$1 } 
    ; 
expr: 

    | PRINT str { Print $2 } 
    | PRINT str expr { Print $2 } 
    | GET_LINE INT str { Print_line_in_file ($2, $3) } 
    | GET_LINE INT str expr { Print_line_in_file ($2, $3) }   
    ; 

编辑

这是我的词法分析器,我试图把它简化,尽可能找到这个错误。

(* File lexer.mll *) 

{ 
    open Parser 
} 

rule main = parse 
    | [' ''\t''\n']  { main lexbuf } 
    | "print_line_in_file" { GET_LINE } 
    | "print" { PRINT} 
    | ['1' - '9']+ as lxm { INT(int_of_string lxm) } 
    | ['a'-'z''A'-'Z'] ['a'-'z''A'-'Z''0'-'9']* as lxm { STRING lxm } 
    | eof {EOF} 

Main.ml

open Path 

let _ = 
    try 
    let filename = Sys.argv.(1) 
    in 
     let lexbuf = Lexing.from_channel (open_in filename) 
     in 
      let result = Parser.main Lexer.main lexbuf 
      in 
       command result; 
       flush stdout 
    with Parsing.Parse_error -> print_string "Error! Check syntax"; 
    flush stdout 

回答

2

要在gasche的答复扩大,你需要改变你的分析器定义如下:

%type <Path.term list> main 
%% 

main: 
    | expr EOL main {$1::$3} 
    | expr EOF  {[$1]} 
    | EOF   {[]} /* if you want to allow a redundant EOL at the end */ 
; 

有了您的原始定义,一行被认为是main一个完整的解析,这就是为什么后您的解析器停止。

+0

我得到的另一个问题是“此表达式具有类型Path.term列表,但表达式期望类型Path.term”。反正有解决这个问题吗?这个错误发生在主...在命令结果行上。是否有任何提示,我可以修复它? –

+1

解析器现在返回一个命令列表,因此您需要执行'List.iter命令结果',或者沿着这些行。 –

+0

谢谢谢谢谢谢谢谢! –

2

每次调用解析器的时候,它只会解析一个表达式(这是你的起点规则的类型);并且它会在行尾停止(给出在文法中如何使用EOL)。如果你想解析几个表达式,你需要在循环中多次调用它。

+0

我明白了!解释器读取文件中的所有行!但它不会执行除程序中第一行外的所有内容!这就是我完全不明白 –

+0

看来你不明白yacc,或者你不在这里发布的调用者中的错误。请发布一整套可编辑的,自包含的简化代码,它们可以重现您的问题。 – camlspotter

+0

我加了!有一个路径文件,其中包含用ocaml编写的可执行命令,它们都可以正常工作!请再次看看这个问题。先谢谢了! –