0

I need to take some decisions depending on the structure and information in a parse tree, this is an example of the trees I am generating now:

Parse Tree

The decisions for generating code will depend on the operator(";","AND","OR","XOR") between two workflows, for instance the code I need to generate from this tree is

mustPrecede(T6,T4) AND mustPrecede(T6,T1) 
AND  mustPrecede(T4,T5) AND  mustPrecede(T1,T5)

For this I need to find out that the operator between T6 and (T4 AND T1) is ";" (sequential composition operator) for taking a decision and then I need to find out that between T4 and T1 the operator is "AND" and then I need to get the T4 and T1 to make a relation with T5. My question is how can I encode this in a parser?.

This is my grammar definition

grammar Hello;      

execution: workflow EOF;

workflow : Task 
         | workflow OPERATOR workflow 
         |'(' workflow (OPERATOR workflow)+ ')' 
         ;

Task : 'T' ('0'..'9')+ 
     | 'WF' ('0'..'9')+
     ;

OPERATOR: 'AND' 
        | 'OR'  
        | 'XOR' 
        | ';' 
        ;

WS  :   [ \t\n\r]+ -> channel(HIDDEN) ; 
Sam Harwell
  • 97,721
  • 20
  • 209
  • 280
user3723800
  • 145
  • 7

1 Answers1

4

You created one token, OPERATOR, which represents all of your operators. This makes it very difficult to distinguish between the different operators. An easier set of rules would be the following:

operator
  : AND
  | OR
  | XOR
  | SEMI
  ;

AND : 'AND';
OR  : 'OR';
XOR : 'XOR;
SEMI : ';';

You would also replace references to OPERATOR with references to operator. Then, in your implementation of a listener or visitor, you could create methods like the following (using an example from a listener).

@Override
public void enterWorkflow(WorkflowContext ctx) {
  List<? extends OperatorContext> operatorContexts = ctx.operator();
  if (operatorContexts.isEmpty()) {
    // handle just a Task
  } else {
    for (OperatorContext operatorContext : ctx.operator()) {
      switch (operatorContext.getStart().getType()) {
      case HelloLexer.AND:
        // handle 'AND'
        break;
      case HelloLexer.OR:
        // handle 'OR'
        break;
      case HelloLexer.XOR:
        // handle 'XOR'
        break;
      case HelloLexer.SEMI:
        // handle ';'
        break;
      default:
        throw new IllegalStateException("Unrecognized operator.");
      }
    }
  }
}
Sam Harwell
  • 97,721
  • 20
  • 209
  • 280
  • this makes sense for making a difference between the operators thanks, perhaps my problem (question) was more about how to deal with the levels in the tree, what I mean with this is how to navigate it. From your answer I can infer that the implementation of a visitor is the way , can you suggested me where can I find more information in relation to this? thanks a lot. – user3723800 Jul 24 '14 at 14:18
  • See related question: http://stackoverflow.com/questions/15050137/once-grammar-is-complete-whats-the-best-way-to-walk-an-antlr-v4-tree?rq=1 – GRosenberg Jul 25 '14 at 01:20