Question

I'm using an ANTLR3 grammar to parse a simple scripting language. I am generating lexer and parser for both C and Java. Now on the C target, everything works fine, but when using the Java target, nested array initializers are not parsed correctly.

For example, if i use this input: "{ 1, 2, { 3, 4 } }"
the parser returns the following: (.array 1 2 .array)
but I would expect this: (.array 1 2 (.array 3 4))

The second array node doesn't have any children. As I said, the parser generated for C works just fine. Does anyone know why this could happen?

This is the part of the grammar that is probably most relevant to the problem. It's probably not the best grammar, but so far it did its job just fine:

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)*;
Was it helpful?

Solution

Start by not doing this: ^(value). It should be value. that might fix it. A node is a tree, no need to say it's a tree.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top