Как Camlp5 (бывший Camlp4) анализирует выражения

Насколько я мог понять, по поиску в Интернете, похоже, что Camlp5 (бывший Camlp4) использует парсер рекурсивного спуска, в то время как ocamlyacc основанный на LALR генератор парсера

В генераторе синтаксического анализатора LALR приоритет и ассоциативность отображаются для сдвига / уменьшения конфликтов. Мой вопрос заключается в том, как рекурсивный анализатор спуска, такой как Camlp5, может иметь дело с декларативным приоритетом оператора?

 # let expr = Grammar.Entry.create gram "expr";;
 # EXTEND
     expr:
       [ "add" LEFTA
         [ x = expr; "+"; y = expr -> x + y
         | x = expr; "-"; y = expr -> x - y ]
       | "mult" RIGHTA
         [ x = expr; "*"; y = expr -> x * y
         | x = expr; "/"; y = expr -> x / y ]
       | "simple" NONA
         [ x = INT -> int_of_string x
         | "("; e = expr; ")" -> e ] ]
     ;
   END;;

Как это относится к леворекурсивным вызовам? Использует ли camlp5 (camlp4) подход приоритета операторов, управляемый таблицей: https://en.wikipedia.org/wiki/Operator-precedence_parser

Любые идеи или ссылки на внутреннюю работу парсера Camlp4 очень ценятся.

1 ответ

Парсер рекурсивного спуска не является табличным парсером, как LALR. Решения, принимаемые синтаксическим анализатором, жестко закодированы в теле функций (каждое правило является функцией). И действительно, CamlpN компилирует грамматическое определение в набор взаимных рекурсивных функций. Выигрышным моментом здесь является то, что вам не нужно кодировать эти функции вручную. Таким образом, если вы изменяете грамматику, вы просто обновляете определение грамматики, и все необходимые функции обновляются для вас. В обычном рекурсивном парсере с ручным кодом вам нужно будет обновить его самостоятельно, что очень подвержено ошибкам.

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