У меня две грамматики:
Здравствуйте. G4:
grammar Hello;
start: exp? EOF;
exp: int_exp | vector_exp;
int_exp: int_exp '*' int_exp | int_exp '+' int_exp | INT;
vector_exp: vector_exp '*' int_exp | int_exp '*' vector_exp |
vector_exp '+' vector_exp | VECTOR;
INT : ('0'..'9') | (('1'..'9')('0'..'9')+);
VECTOR: 'v';
WS : [ \t\r\n]+ -> skip ;
Hello2.g4
grammar Hello2;
start: exp? EOF;
exp: add;
add: add '+' add | mult '+' add | add '+' mult | mult;
mult: mult '*' mult | INT '*' mult | mult '*' INT | INT | VECTOR;
INT : ('0'..'9') | (('1'..'9')('0'..'9')+);
VECTOR: 'v';
WS : [ \t\r\n]+ -> skip ;
Первая грамматика проверяет типы правильно: добавление вектора к скалярному v+1
не работает. Но он не имеет правильного порядка действий.
1+1*v
дает
Вторая грамматика имеет правильный порядок, но допускает v+1
, что не должно работать.
Я понимаю, что Почему грамматики работают так, но я не могу объединить эти два, создавая грамматику, которая проверяет типы и имеет правильный порядок операций.
Что бы я ни проверял в первую очередь, моя проблема в том, что я должен начать где-то ломать то, что я делаю во вторую очередь. Как совместить эти два требования?
Не разрешать добавлять скаляр к вектору - это семантическое правило, а не синтаксическое. Парсер может покрывать только синтаксические правила. Вы должны применить семантические правила после синтаксического анализа, например в посетителе, который проходит по созданному дереву синтаксического анализа.
Как выглядят семантические правила, решать вам. Это не меняет общей идеи: применяйте их на втором этапе после того, как вы закончите синтаксический анализ.
Но что, если мои скаляры всегда являются числами, а мои векторы всегда являются строками, это невозможно или плохая идея?