parsing tree antlr3

parsing - Parse apiló la expresión de comparación en Conjunction Tree lógico con antlr3



(1)

Me encontré con un problema cuando intenté analizar una expresión de comparación aritmética apilada:

"1<2<3<4<5"

en un Árbol de Conjunciones lógico:

CONJUNCTION(COMPARISON(1,2,<) COMPARISON(2,3,<) COMPARISON(3,4,<) COMPARISON(4,5,<))

¿Hay alguna forma en las reglas de reescritura de árboles Antlr3 para iterar a través de tokens coincidentes y crear el árbol de resultados de ellos en el idioma de destino (estoy usando Java)? Así que podría crear nodos COMPARACIÓN de elemento x, x-1 de tokens ''suma'' coincidentes. Sé que puedo hacer referencia al último resultado de una regla, pero de esa manera solo obtendría reglas de COMPARACIÓN compiladas, eso no es lo que deseo.

/This is how i approached the problem, sadly it doesn''t do what i would like to do yet of course. fragment COMPARISON:; operator : (''<''|''>''|''<=''|''>=''|''==''|''!='') ; comparison @init{boolean secondpart = false;} : e=addition (operator {secondpart=true;} k=addition)* -> {secondpart}? ^(COMPARISON ^(VALUES addition*) ^(OPERATORS operator*)) -> $e ; //Right now what this does is: tree=(COMPARISON (VALUES (INTEGERVALUE (VALUE 1)) (INTEGERVALUE (VALUE 2)) (INTEGERVALUE (VALUE 3)) (INTEGERVALUE (VALUE 4)) (INTEGERVALUE (VALUE 5))) (OPERATORS < < < <)) //The label for the CONJUNCTION TreeNode that i would like to use: fragment CONJUNCTION:;


Se me ocurrió una desagradable solución a este problema al escribir código de construcción de árbol real de Java:

grammar testgrammarforcomparison; options { language = Java; output = AST; } tokens { CONJUNCTION; COMPARISON; OPERATOR; ADDITION; } WS : (''/t'' | ''/f'' | '' '' | ''/r'' | ''/n'' )+ {$channel = HIDDEN;} ; comparison @init { List<Object> additions = new ArrayList<Object>(); List<Object> operators = new ArrayList<Object>(); boolean secondpart = false; } : (( e=addition {additions.add(e.getTree());} ) ( op=operator k=addition {additions.add(k.getTree()); operators.add(op.getTree()); secondpart = true;} )*) { if(secondpart) { root_0 = (Object)adaptor.nil(); Object root_1 = (Object)adaptor.nil(); root_1 = (Object)adaptor.becomeRoot( (Object)adaptor.create(CONJUNCTION, "CONJUNCTION") , root_1); Object lastaddition = additions.get(0); for(int i=1;i<additions.size();i++) { Object root_2 = (Object)adaptor.nil(); root_2 = (Object)adaptor.becomeRoot( (Object)adaptor.create(COMPARISON, "COMPARISON") , root_2); adaptor.addChild(root_2, additions.get(i-1)); adaptor.addChild(root_2, operators.get(i-1)); adaptor.addChild(root_2, additions.get(i)); adaptor.addChild(root_1, root_2); } adaptor.addChild(root_0, root_1); } else { root_0 = (Object)adaptor.nil(); adaptor.addChild(root_0, e.getTree()); } } ; /** lowercase letters */ fragment LOWCHAR : ''a''..''z''; /** uppercase letters */ fragment HIGHCHAR : ''A''..''Z''; /** numbers */ fragment DIGIT : ''0''..''9''; fragment LETTER : LOWCHAR | HIGHCHAR ; IDENTIFIER : LETTER (LETTER|DIGIT)* ; addition : IDENTIFIER ->^(ADDITION IDENTIFIER) ; operator : (''<''|''>'') ->^(OPERATOR ''<''* ''>''*) ; parse : comparison EOF ;

Para la entrada

"DATA1 < DATA2 > DATA3"

Este árbol de salidas como:

Si conocen alguna solución mejor, por favor hábleme de ellos