Проблемы с файлом грамматики SableCC
Кажется, у меня есть проблемы с SableCC, генерирующим соответствующие лексеры, узлы и анализируемые вещи, которые он обычно автоматически генерирует из файла грамматики. Я не реализую абстрактное синтаксическое дерево в данный момент.
Когда я пытаюсь запустить SableCC с файлом грамматики ниже, я получаю следующую ошибку:
[41,33] Переопределение AFunctionHead.Id. Я знаю, в чем проблема, но, похоже, что-то происходит в сфере производства. Возможно, я что-то упустил?
Package Grammar_Specification;
Helpers
digit = ['0'..'9'];
letter = (['a'..'z'] | ['A'..'Z']);
underscore = '_';
plus = '+';
minus = '-';
mult = '*';
div = '/';
equals = '=';
l_par = '(';
r_par = ')';
l_curly = '{';
r_curly = '}';
unicode_input_character = [0..0xffff];
lf = 0x000a;
cr = 0x000d;
line_terminator = lf | cr | cr lf;
input_character = [unicode_input_character - [cr + lf]];
not_star = [input_character - '*'] | line_terminator;
not_star_not_slash = [input_character - ['*' + '/']] | line_terminator;
multi_line_comment = '/*' not_star+ '*'+ (not_star_not_slash not_star* '*'+)* '/';
line_comment = '//' input_character* line_terminator?;
Tokens
func = 'FUNC';
id = (letter(letter | digit | underscore)* | underscore(letter | digit | underscore)*);
float_literal = minus? digit (digit)* ('.' (digit)*)? (('e' | 'E') (plus | minus)? digit (digit)*)?;
whitespace = (' ' | '\t' | '\n' | '\r')+;
comment = multi_line_comment | line_comment;
Productions
program = function_decl*statement*;
function_decl = function_head function_body;
function_head = func id l_par id r_par;
function_body = l_curly statement* r_curly;
statement = id equals expression;
expression = expression plus term |
expression minus term |
term;
term = term mult factor |
term div factor |
factor;
factor = l_par expression r_par |
identifier l_par expression r_par |
float_literal |
id;
1 ответ
Это объясняется в документации SableCC, магистерской диссертации Этьена Ганьона:
В отличие от альтернатив, элементы имеют очевидного кандидата на имя, которое является идентификатором самого элемента. Это будет работать, пока элемент не появляется дважды в одной и той же альтернативе. В этом случае для текущей версии SableCC требуется имя хотя бы одного из двух элементов. (Для обратной совместимости одно вхождение повторяющегося элемента может остаться безымянным). SableCC выдаст ошибку, если не предоставлено достаточно имен. Имена элементов указываются с помощью префикса элемента с идентификатором в квадратных скобках, за которым следует двоеточие.
Другими словами, вы не можете использовать id
дважды в производстве для function_head
без указания хотя бы одного из них (независимо от того, генерируете ли вы AST или нет).
Попробуйте что-то вроде этого:
function_head = func id l_par [parameter]:id r_par;