#antlr4
#antlr4
Вопрос:
Мне нужно реализовать синтаксический анализатор для этого типа логики: указанная грамматика
Символ S является начальным символом грамматики; L, T, R, V, K, D, F и E обозначают нетерминальные символы. Конечный символ c соответствует одному из двух скалярных типов, указанных в задаче. Символ терминала t соответствует одному из типов данных, которые могут быть описаны в разделе тип. Я создал следующую грамматику:
grammar Parse;
compileString: S ;
S: TYPE L VAR R;
L: T (SEPARATOR|SEPARATOR L);
R: V (SEPARATOR|SEPARATOR R);
V: [a-zA-Z] ([a-zA-Z]| [0-9]|'_')* DEFINITION (D|C);
T: D|C;
TYPE:'type';
VAR:'var';
D: // acceptable data types
'struct'
| 'union'
| 'array'
;
C: 'byte'
|'word' //scalar type
;
SEPARATOR:';';
DEFINITION :':';
WS : [ tnr] -> skip ; // whitespaces
Но когда я пытаюсь выполнить его для построения: «введите byte; var p1:word;», я получаю следующий вывод:
Tokens:
[@0,0:3='type',<6>,1:0]
[@1,5:9='byte;',<2>,1:5]
[@2,11:13='var',<7>,1:11]
[@3,15:22='p1:word;',<3>,1:15]
[@4,23:22='<EOF>',<-1>,1:23]
Parse Tree:
compileString (
<Error>"type"
<Error>"byte;"
<Error>"var"
<Error>"p1:word;"
)
Я не понимаю, в чем может быть проблема, отладка выполнялась в VS Code с помощью плагина от Antlr. Буду рад любому ответу!
Ответ №1:
В ANTLR правила лексера начинаются с заглавных букв, а правила синтаксического анализатора — со строчных букв. Итак, все ваши правила, кроме compileString
правил лексера.
S: TYPE L VAR R;
не соответствует вводу type byte; var p1:word;
, потому что в нем есть пробелы, и ничто в определении S
не соответствует пробелам. Вы, вероятно, думаете, что это не должно иметь значения, потому что вы пропускаете пробелы, но токены пропускаются только между правилами лексера, а не внутри них. Так что это сработало бы, если S
бы было правилом синтаксического анализатора, но не как правило лексера.
То же самое относится к пробелам между разделителем и L
/ R
в L
и R
.
PS: Я настоятельно рекомендую давать вашим правилам более длинные имена, поскольку довольно сложно следовать вашей грамматике. Вы также можете рассмотреть возможность использования
оператора в L
и R
вместо рекурсии.
Комментарии:
1. Большое вам спасибо! Ваш комментарий мне очень помог, я сделал так, как вы посоветовали, и все заработало!