2014-03-19 105 views
1

我试图在OCaml中编写解释器,我在这里遇到问题。OCaml解释器:评估函数内部的函数

在我的计划,我想打电话给这样的函数,例如:

print (get_line 4) // print: print to stdout, get_line: get a specific line in a file 

我怎么能这样做?问题出现在我们的解析器中,我认为是这样,因为它定义了程序将如何运行,函数是如何定义的以及程序的流程。这是我迄今为止在解析器中使用的一个词法分析器(代码如下),但似乎并不奏效。我真的没有看到我的代码和OCaml site上的计算器有任何区别,括号内的语句首先被评估,然后将其值返回到其父操作以进行下一次评估。

在我的翻译,功能get_line内部括号是首先评估,但我不认为它返回值为print函数,或它只是错误的类型(检查,但我不认为这是这个错误) 。

计算器和我的解释器之间的一个区别是,计算器正在使用原始类型,我的功能。但他们应该是相似的。

这是我的代码,只是它的一部分:

parser.mly:

%token ODD 
%token CUT 
%start main 
%type <Path.term list> main 
%% 

main: 
    | expr EOL main {$1 :: $3} 
    | expr EOF { [$1] } 
    | EOL main { $2 } 
; 
expr: 
     | ODD INT { Odd $2} 
    | ODD LPAREN INT RPAREN expr { Odd $3 } 
     | CUT INT INT { Cut ($2, $3)} 
    | CUT INT INT expr { Cut ($2, $3) } 

lexer.mll:

{ 
    open Parser 
} 
(* define all keyword used in the program *) 
rule main = 
    parse 
     | ['\n'] { EOL } 
     | ['\r']['\n'] { EOL } 
     | [' ''\t''\n']  { main lexbuf }  
     | '('  { LPAREN } 
     | ')'  { RPAREN } 
     | "cut" { CUT }  
     | "trunclength" { TRUNCLENGTH } 
     | "firstArithmetic" { FIRSTARITH } 
     | "f_ArithmeticLength" { F_ARITHLENGTH } 
     | "secondArithmetic" { SECARITH } 
     | "s_ArithmeticLength" { S_ARITHLENGTH } 
     | "odd" { ODD } 
     | "oddLength" { ODDLENGTH } 
     | "zip" { ZIP } 
     | "zipLength" { ZIPLENGTH } 
     | "newline" { NEWLINE } 
     | eof { EOF }    
     | ['0' - '9']+ as lxm { INT(int_of_string lxm) } 
     | ['a'-'z''A'-'Z'] ['a'-'z''A'-'Z''0'-'9']* as lxm { STRING lxm } 

回答

0
| ODD LPAREN INT RPAREN expr { Odd $3 } 

你的语法规则需要INT括号之间。您需要将其更改为expr。还有其他一些问题,但我会留下来。

0

首先,你的解析器只会尝试建立一个Path.term的列表,但是你想用它做什么?

然后,解析器有很多错误,所以我真的不知道从哪里开始。例如,expr规则的第二种和第四种情况完全忽略了最后的expr。而且,解析器只认表达式包含 “奇<INT>”(或 “奇(<INT>)”)和 “切<INT> <INT>”,所以它应该如何评价printget_line?您应该编辑您的问题并尝试使其更清晰。

计算表达式,你可以

  • 做直接内部的语义动作(如计算器的例子),
  • 或(更好)建立一个AST(抽象语法树)与您解析器然后解释它。

如果你想诠释print (get_line 4),解析器需要知道什么printget_line意思。在您的代码中,您的解析器将看到printget_line作为STRING标记(具有字符串值)。由于它们似乎是您的语言中的关键词,因此您的词法分析器应该识别它们并返回特定的标记。

+0

Path.term在我们的解释器中定义,所以它可以,我认为:) –

+0

好的,但它用于什么?它与你想要做什么有关:“解释一个程序”? –

+0

该文件包含我们在词法分析器中定义的关键字将使用的所有函数。所以当我调用在我的程序中的词法分析器中定义的关键字时,它将被解析器解析,然后与解析的关键字(在expr ....中)对应的函数将执行并给我答案。我希望这很清楚。 –