1

我正在尝试编写解释器,OCaml但这里有问题。

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

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

我怎样才能做到这一点?问题出在我们的解析器中,我认为它定义了程序的运行方式、函数的定义方式以及程序的流程。这是我迄今为止在解析器和词法分析器中所拥有的(下面的代码),但它似乎没有用。我真的看不出我的代码和OCaml 网站上的计算器有什么区别,括号内的语句首先被评估,然后将其值返回给其父操作以进行下一次评估。

在我的解释器中,get_line括号内的函数首先被评估,但我认为它不会将值返回给print函数,或者它确实返回了错误的类型(检查过,但我认为不是这个错误)。

计算器和我的解释器之间的一个区别是计算器使用原始类型,我的是函数。但它们应该是相似的。

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

解析器.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) }

词法分析器.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  }
4

2 回答 2

0

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

然后,您的解析器有很多问题,所以我真的不知道从哪里开始。例如,expr规则的第二个和第四个案例完全忽略了最后一个expr。此外,您的解析器只能识别包含“odd <int>”(或“odd (<int>)”)和“cut <int> <int>”的表达式,那么它应该如何评估printget_line?您应该编辑您的问题并尝试使其更清晰。

要评估表达式,您可以

  • 直接在语义动作中执行(如在计算器示例中),
  • 或者(更好)用你的解析器构建一个 AST(用于抽象语法树)然后解释它。

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

于 2014-03-19T14:21:13.883 回答
0
| ODD LPAREN INT RPAREN  expr { Odd $3 }

您的语法规则需要一个INT括号。您需要将其更改为expr. 这还有许多其他问题,但我会留在那里。

于 2014-03-19T13:20:10.167 回答