Интерпретатор OCaml: оцените функцию внутри функции
Я пытаюсь написать переводчик в OCaml
и у меня проблема здесь.
В моей программе я хочу вызвать такую функцию, например:
print (get_line 4) // print: print to stdout, get_line: get a specific line in a file
Как я могу это сделать? Я думаю, что проблема в нашем парсере, так как он определяет, как будет выполняться программа, как будет определена функция и как будет выполняться программа. Это то, что я до сих пор имел в синтаксическом анализаторе лексера (код ниже), но, похоже, он не работал. На самом деле я не вижу никакой разницы между моим кодом и калькулятором на сайте OCaml, оператор внутри скобки сначала оценивается, а затем возвращает его значение родительской операции для следующей оценки.
В моем переводчике функция 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 }
2 ответа
| ODD LPAREN INT RPAREN expr { Odd $3 }
Ваше правило грамматики требует INT
между скобками. Вы должны изменить это на expr
, Есть ряд других проблем с этим, но я оставлю это на этом.
Во-первых, ваш парсер пытается только создать список Path.term
а что ты хочешь с этим делать?
Кроме того, с вашим парсером многое не так, поэтому я не знаю, с чего начать. Например, второй и четвертый случай expr
Правило полностью игнорирует последнее expr
, Более того, ваш синтаксический анализатор распознает только выражения, содержащие "odd print
а также get_line
? Вы должны отредактировать свой вопрос и попытаться прояснить его.
Чтобы оценить выражения, вы можете
- сделать это непосредственно внутри семантических действий (как в примере калькулятора),
- или (лучше) построить AST (для абстрактного синтаксического дерева) с вашим анализатором и затем интерпретировать его.
Если вы хотите интерпретировать print (get_line 4)
твой парсер должен знать что print
а также get_line
имею в виду. В вашем коде ваш парсер увидит print
или же get_line
как STRING
токен (имеющий строковое значение). Поскольку они кажутся ключевыми словами на вашем языке, ваш лексер должен их распознать и вернуть определенный токен.