Я использую грамматику ANTLR3 для анализа простого языка сценариев. Я создаю lexer и parser для C и Java. Теперь на цель C все работает отлично, но при использовании целевой Java, инициализаторы вложенных массивов не обрабатываются правильно.Парсер ANTLR3 не обрабатывает вложенные массивы правильно, но только на выходе Java
Например, если я использую этот вход: "{ 1, 2, { 3, 4 } }"
анализатор возвращает следующее: (.array 1 2 .array)
, но я бы ожидать, что это: (.array 1 2 (.array 3 4))
Второй узел массива не имеет детей. Как я уже сказал, синтаксический анализатор, сгенерированный для C, отлично работает. Кто-нибудь знает, почему это может произойти?
Это часть грамматики, которая, вероятно, наиболее важна для проблемы. Это, вероятно, не самая лучшая грамматика, но до сих пор он сделал свою работу просто отлично:
expression: while_expression;
while_expression: LITERAL_WHILE T_LPAREN expr_assignment T_RPAREN T_LBRACE params? T_RBRACE -> ^(Op_while[".while"] expr_assignment params?) |
expr_assignment;
expr_assignment: expr_conditional (T_ASSIGN^ expr_conditional)?;
expr_conditional: LITERAL_IF T_LPAREN condif=expr_logical_or T_RPAREN LITERAL_THEN? alti1=expr_logical_or (LITERAL_ELSE alti2=expr_logical_or)? -> ^(Op_if[".if"] $condif $alti1 $alti2) |
(
(condc=expr_logical_or -> expr_logical_or)
(T_QMARK altc1=expr_conditional T_COLON altc2=expr_conditional -> ^(T_QMARK $condc $altc1 $altc2))?
);
expr_logical_or: expr_logical_and (T_LOG_OR^ expr_logical_and)*;
expr_logical_and: expr_bitwise_or (T_LOG_AND^ expr_bitwise_or)*;
expr_bitwise_or: expr_bitwise_xor (T_BIT_OR^ expr_bitwise_xor)*;
expr_bitwise_xor: expr_bitwise_and (T_BIT_XOR^ expr_bitwise_and)*;
expr_bitwise_and: expr_equality (T_BIT_AND^ expr_equality)*;
expr_equality: expr_relational ((T_EQ^|T_NEQ^) expr_relational)*;
expr_relational: expr_shift ((T_LT^|T_LTE^|T_GT^| T_GTE^) expr_shift)*;
expr_shift: expr_additive ((T_SHL^|T_SHR^) expr_additive)*;
expr_additive: expr_multiplicative ((T_PLUS^|T_MINUS^) expr_multiplicative)*;
expr_multiplicative: expr_unary ((T_MULT^|T_DIV^|T_MOD^|T_POW^) expr_unary)*;
expr_unary: T_PLUS expr_primary -> ^(Op_prefix[".prefix"] T_PLUS expr_primary) |
T_MINUS expr_primary -> ^(Op_prefix[".prefix"] T_MINUS expr_primary) |
T_NOT expr_primary -> ^(Op_prefix[".prefix"] T_NOT expr_primary) |
T_NEG expr_primary -> ^(Op_prefix[".prefix"] T_NEG expr_primary) |
T_INC expr_primary -> ^(Op_prefix[".prefix"] T_INC expr_primary) |
T_DEC expr_primary -> ^(Op_prefix[".prefix"] T_DEC expr_primary) |
expr_primary;
expr_primary: (expr_object->expr_object)
(
T_LBRACKET args=params T_RBRACKET -> ^(Op_index[".index"] $expr_primary $args) |
T_DOT id=val_id T_LPAREN argsopt=params_opt T_RPAREN -> ^(Op_thiscall[".thiscall"] $id $expr_primary $argsopt) |
T_DOT id=val_id -> ^(Op_property[".property"] $id $expr_primary) |
T_INC -> ^(Op_postfix[".postfix"] T_INC $expr_primary) |
T_DEC -> ^(Op_postfix[".postfix"] T_DEC $expr_primary)
)*;
expr_object: value -> ^(value) |
array_initializer -> ^(array_initializer) |
(T_LPAREN expression T_RPAREN) -> ^(expression) |
method_call -> ^(method_call) |
LITERAL_BREAK -> ^(Op_break[".break"]);
method_call: val_id T_LPAREN params_opt T_RPAREN -> ^(Op_call[".call"] val_id params_opt);
array_initializer: T_LBRACE params_opt T_RBRACE -> ^(Op_array[".array"] params_opt);
params_opt: params?;
params: expression (T_COMMA! expression)*;
Есть ли какие-либо конкретные причины, почему u arent использует новейшую версию ANTLR ..? Новейшим является ANTLR4 – Ben
@Ben Первоначально у нас был только C-Target в качестве требования, который недоступен для V4, и я хотел бы сохранить ту же базу кода. – Botz3000