Интерпретатор 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 " (или "odd ()") и "cut ", так как он должен оценивать print а также get_line? Вы должны отредактировать свой вопрос и попытаться прояснить его.

Чтобы оценить выражения, вы можете

  • сделать это непосредственно внутри семантических действий (как в примере калькулятора),
  • или (лучше) построить AST (для абстрактного синтаксического дерева) с вашим анализатором и затем интерпретировать его.

Если вы хотите интерпретировать print (get_line 4)твой парсер должен знать что print а также get_line имею в виду. В вашем коде ваш парсер увидит print или же get_line как STRING токен (имеющий строковое значение). Поскольку они кажутся ключевыми словами на вашем языке, ваш лексер должен их распознать и вернуть определенный токен.

Другие вопросы по тегам