Я пишу лексер и парсер на ocamllex и ocamlyacc следующим образом. function_name
и table_name
- это одно и то же регулярное выражение, т.е. строка, содержащая только английский алфавит. Единственный способ определить, является ли строка function_name
или table_name
, - это проверить ее окружение. Например, если такая строка окружена [
и ]
, то мы знаем, что это table_name
. Вот текущий код:
In lexer.mll
,
... ...
let function_name = ['a'-'z' 'A'-'Z']+
let table_name = ['a'-'z' 'A'-'Z']+
rule token = parse
| function_name as s { FUNCTIONNAME s }
| table_name as s { TABLENAME s }
... ...
In parser.mly
:
... ...
main:
| LBRACKET TABLENAME RBRACKET { Table $2 }
... ...
Как я писал | function_name as s { FUNCTIONNAME s }
перед | table_name as s { TABLENAME s }
, приведенный выше код не смог проанализировать [haha]
; сначала он рассматривал haha
как function_name
в лексере, затем он не смог найти для него ни одного соответствующего правила в анализаторе. Если бы он мог рассматривать haha
как table_name
в лексере, он бы соответствовал [haha]
как таблице в анализаторе.
Один из способов решения этой проблемы - точнее использовать лексер. Например, мы определяем let table_name_with_brackets = '[' ['a'-'z' 'A'-'Z']+ ']'
и | table_name_with_brackets as s { TABLENAMEWITHBRACKETS s }
в лексере. Но я хотел бы знать, есть ли другие варианты. Разве нельзя заставить лексер и синтаксический анализатор работать вместе, чтобы определять токены и сокращение?
function_name
иtable_name
вообще разные типы токенов? - person user2357112 supports Monica   schedule 12.08.2020function_name
не совсем то же самое, что иtable_name
. Они не совсем то же самое, но они перекрывают друг друга. - person SoftTimur   schedule 12.08.2020