Разбор грамматики без кофеина в Antlr4 - PullRequest
0 голосов
/ 12 апреля 2020

Я создаю правила парсера и лексера для языка программирования Decaf, написанного на ANTLR4. Есть тестовый файл анализатора, который я пытаюсь запустить, чтобы получить для него дерево синтаксического анализатора, напечатав посещенные узлы в окне терминала и вставив их в класс D3_parser_tree.html. В текущем дереве синтаксического анализа отсутствуют правильные квадратные скобки с номером 10 в соответствии с этим файлом тестирования: class program { int i [10]; } parser tree

Полученная ошибка: mismatched input '10' expecting INT_LITERAL

Я не уверен, почему я получаю эту ошибку, хотя я объявил правило лексера для INT_LITERAL, а затем вызвал его в правиле синтаксического анализатора в field_decl в соответствии с заданным параметром Decaf c:

** Parser rules **

<program> → class Program ‘{‘ <field_decl>* <method_decl>* ‘}’
<field_decl> → <type> { <id> | <id> ‘[‘ <int_literal> ‘]’ }+, ;
<method_decl> → { <type> | void } <id> ( [ { <type> <id> }+, ] ) <block>
<digit> → 0 | 1 | 2 | … | 9
<block> → ‘{‘ <var_decl>* <statement>* ‘}’
<literal> → <int_literal> | <char_literal> | <bool_literal>
<hex_digit> → <digit> | a | b | c | … | f | A | B | C | … | F
<int_literal> → <decimal_literal> | <hex_literal>
<decimal_literal> → <digit> <digit>*
<hex_literal> → 0x <hex_digit> <hex_digit>*

Связанные правила Lexer:

NUMBER : [0-9]+;
fragment ALPHA : [_a-zA-Z0-9];
fragment DIGIT : [0-9];
fragment DECIMAL_LITERAL : DIGIT+;
CHAR_LITERAL : '\'' CHAR '\'';
STRING_LITERAL : '"' CHAR+ '"' ;
COMMENT : '//' ~('\n')* '\n' -> skip;
WS : (' ' | '\n' | '\t' | '\r') + -> skip;

Связанные правила парсера:

program : CLASS VAR LCURLYBRACE field_decl*method_decl* RCURLYBRACE EOF;
field_decl : data_type field ( COMMA field )* SEMICOLON;

Пожалуйста, дайте мне знать, если вам нужна дополнительная информация и Я очень ценю вашу помощь.

1 Ответ

0 голосов
/ 12 апреля 2020

Конфликт следующих правил:

VAR : ALPHA+;
...
NUMBER : [0-9]+;
...
INT_LITERAL : DECIMAL_LITERAL | HEX_LITERAL;

Все они соответствуют 10, но лексер всегда выберет VAR, так как это правило определено первым.

Это просто как работает лексер ANTLR: он пытается соответствовать как можно большему количеству символов, и когда два (или более) правила соответствуют одинаковому количеству символов, первое определенное «выигрывает».

Вы увидите, что оно правильно анализирует, если вы измените field на:

field : VAR | VAR LSQUAREBRACE VAR RSQUAREBRACE;
...