OCaml解释器:在函数中计算函数

OCaml解释器:在函数中计算函数,ocaml,interpreter,ocamlyacc,ocamllex,Ocaml,Interpreter,Ocamlyacc,Ocamllex,我正试图用OCaml编写一个解释器,我遇到了一个问题 在我的程序中,我想调用如下函数,例如: print (get_line 4) // print: print to stdout, get_line: get a specific line in a file 我该怎么做?问题是在我们的解析器中,我认为是这样的,因为它定义了一个程序如何运行,一个函数如何定义,以及一个程序的流程。这是我目前在下面的语法分析器代码中看到的,但它似乎不起作用。我看不出我的代码和上的计算器有什么区别,括号内的语

我正试图用OCaml编写一个解释器,我遇到了一个问题

在我的程序中,我想调用如下函数,例如:

print (get_line 4)  // print: print to stdout, get_line: get a specific line in a file
我该怎么做?问题是在我们的解析器中,我认为是这样的,因为它定义了一个程序如何运行,一个函数如何定义,以及一个程序的流程。这是我目前在下面的语法分析器代码中看到的,但它似乎不起作用。我看不出我的代码和上的计算器有什么区别,括号内的语句首先求值,然后将其值返回到其父操作以进行下一次求值

在我的解释器中,括号内的函数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) }

语法规则要求括号之间有一个INT。您需要将其更改为expr。这还有许多其他问题,但我就不谈了。

首先,您的解析器只尝试构建Path.term的列表,但您想用它做什么

然后,你的解析器有很多问题,所以我真的不知道从哪里开始。例如,expr规则的第二种和第四种情况完全忽略了最后一种expr。此外,解析器只识别包含奇数或奇数和剪切的表达式,那么它应该如何计算print和get_line呢?你应该修改你的问题,尽量让它更清楚

要计算表达式,可以

直接在语义动作中执行,如计算器示例中所示, 或者最好用解析器为抽象语法树构建一个AST,然后对其进行解释。
如果要解释print get_行4,解析器需要知道print and get_行的含义。在代码中,解析器将print或get_行视为具有字符串值的字符串标记。因为它们似乎是您语言中的关键词,您的词法分析器应该识别它们并返回一个特定的标记。

Path.term在我们的解释器中定义,所以它是可以的。我想:可以,但它的用途是什么?它与您想要做的事情有什么关系:intrepret程序?该文件包含lexer中定义的关键字将使用的所有函数。因此,当我在程序中调用lexer中定义的关键字时,它将被解析器解析,然后是expr中解析的关键字对应的函数。。。。将执行并给我答案。我希望这是清楚的。那么,你想用expr lexing规则做什么呢?您能否给出一个有效输入的奇数和切数示例,以及预期结果Path.term列表的内容?
{
    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  }
| ODD LPAREN INT RPAREN  expr { Odd $3 }