#antlr #antlr4
#antlr #antlr4
Вопрос:
Я создавал анализатор грамматики с использованием Antlr4 и хотел добавить переназначение переменной (без необходимости объявлять новую переменную)
Я пытался изменить оператор переназначения на выражение, но это ничего не изменило
Вот сокращенная версия моей грамматики:
grammar MyLanguage;
program: statement* EOF;
statement
: expression EOC
| variable EOC
| IDENTIFIER ASSIGNMENT expression EOC
;
variable: type IDENTIFIER (ASSIGNMENT expression)?;
expression
: STRING
| INTEGER
| IDENTIFIER
| expression MATH expression
| (' ' | '-') expression
;
MATH: ' ' | '-' | '*' | '/' | '%' | '//' | '**';
ASSIGNMENT: MATH? '=';
EOC: ';';
WHITESPACE: [ trn] -> skip;
STRING: '"' (~[u0000-u0008u0010-u001F"] | [t])* '"' | ''' (~[u0000-u0008u0010-u001F'] | [t])* ''';
INTEGER: '0' | (' ' | '-')? [1-9][0-9]*;
IDENTIFIER: [a-zA-Z_][a-zA-Z0-9_]*;
type: 'str';
если что-то еще может иметь отношение к делу, пожалуйста, спросите
итак, я попытался проанализировать
str test = "empty";
test = "not empty";
которая сработала, но когда я попытался (часть функции fibbionaci)
temp = n1;
n1 = n1 n2;
n2 = temp;
он выдал ошибку и проанализировал ее как
temp = n1; //statement
n1 = n1 //statement - <missing ';'>
n2; //statement
n2 = temp; //statement
Комментарии:
1. Выполняет ли он синтаксический анализ
n1 n2
, когда назначение не задействовано? Если это работает до тех пор, пока вы не введете дополнение, то, возможно, проблема в добавлении, а не в назначении.2. Пожалуйста, включите все определения, чтобы кто-нибудь смог воспроизвести проблему.
3. @sepp2k похоже, что это так, я никогда не тестировал это самостоятельно, и это был результат:
n1 /*statement - no viable alternative*/ n2; //statement
4. @BilltheLizard Я добавил все к этим соответствующим определениям (ни у какого другого оператора не возникает проблем)
5. @Dia.Frost по-прежнему не компилируется для меня. После того, как я добавляю
grammar fileName;
в начале, я получаю «ссылку на неопределенное правило» дляWHITESPACE
иconstant_mod
. Пожалуйста, опубликуйте версию вашего кода, которая компилирует и воспроизводит проблему (в идеале вы бы удалили все части, которые не имеют отношения к проблеме, но все же протестировали сокращенную версию, чтобы убедиться, что она компилируется и все еще демонстрирует проблему).
Ответ №1:
Ваша проблема не имеет ничего общего с операторами присваивания. Дополнения просто вообще не работают — независимо от того, являются они частью назначения или нет. Таким образом, простейшим вводом для получения ошибки было бы x y;
. Если вы распечатаете поток токенов для этого ввода (например, используя grun
с -tokens
опцией), вы получите следующий результат:
[@0,0:0='x',<IDENTIFIER>,1:0]
[@1,1:1=' ',<' '>,1:1]
[@2,2:2='y',<IDENTIFIER>,1:2]
[@3,3:3=';',<';'>,1:3]
[@4,4:3='<EOF>',<EOF>,1:4]
line 1:1 no viable alternative at input 'x '
Теперь сравните это с x*y;
, который работает нормально:
[@0,0:0='x',<IDENTIFIER>,1:0]
[@1,1:1='*',<MATH>,1:1]
[@2,2:2='y',<IDENTIFIER>,1:2]
[@3,3:3=';',<';'>,1:3]
[@4,4:3='<EOF>',<EOF>,1:4]
Важным отличием здесь является то, что *
распознается как MATH
токен, но
им не является. Вместо этого он распознается как ' '
токен.
Это происходит потому, что вы ввели отдельный ' '
(и '-'
) тип токена в альтернативе | (' ' | '-') expression
. Таким образом, всякий раз, когда лексер видит
, он создает ' '
токен, а не MATH
токен, потому что строковые литералы в правилах синтаксического анализа имеют приоритет над правилами именованного лексера.
Если вместо этого вы включаете MATH
в правило синтаксического анализа math
(или, возможно mathOperator
), все операторы будут литералами, и проблема исчезнет. Тем не менее, вам, вероятно, не нужно единое правило для всех математических операторов, потому что это не дает вам желаемого приоритета, но это другая проблема.
PS: Что-то вроде x 1
все равно не сработает, потому что оно будет восприниматься 1
как один INTEGER
токен. Вы можете исправить это, удалив из
правила начальные -
и INTEGER
(таким образом, x = -2
это было бы проанализировано как унарный минус, применяемый к целому числу 2
вместо просто целого -2
числа, но это не проблема).
Комментарии:
1. Математический токен фактически уже разделен в моей исходной грамматике, так что это не проблема, я попробую изменить его на правило синтаксического анализа.