Chinese programming Zhihu column original address

1 basic reference https://pragprog.com/book/tpantlr2/the-definitive-antlr-4-reference “Building a Calculator Using a Visitor” section, Added only support for mathematical multiplication and division symbols (×÷). For example, the following equation:

3 * 2 + 8 present 4-2 x 4Copy the code

Source code is still in Program-in-Chinese/Quan5

The space definition has been removed from the previous syntax file. What needs to be explored is the question of priorities. Whether because “expression operator = (‘ * ‘|’/’ | ‘x’ | ‘present’) expression” written in the front, method has the higher priority in syntax analysis.

So far, the Antlr syntax file’s support for Chinese naming is good. The only expedient is that the Token rule must begin with a capital, hence the prefix “T”):

Grammar circle 5; Program: expression; Expression: expression operator = (' * '|'/' | 'x' | 'present') # expression, expression | operator = (' + '|' - ') expression count # # to add and subtract | T; T number: [0-9]+; T added: '+'; T: '-'; T by: '*'; T number times: '×'; T in addition: '/'; T number divided by: '÷';Copy the code

The first time you try the accessibility of # labels. An “expression” syntax rule generates three Visitor methods (below), and the Visitor is still relatively simple. Note: In the grammar rule, either all branches have labels or none. Otherwise generate parser error:

public classCustom accessorextendsAround 5BaseVisitorThe < node >{

  @Override
  publicNumber of nodes visit (number Context Context) {TerminalNode number = Context. T ();returninstanceof ErrorNode ? null : newCount nodes (count.gettext ()); }@Override
  publicNode visit add and subtract (add and subtract Context Context) {expression node node =newExpression node (); Node. Operator = context. Operator. GetType () == circle5Parser. T add? Operation symbol. Plus: operation symbol. Reduction; Left child = visit(context. Expressions (0)); Right child = visit(context. Expressions (1));
    returnNode; }@Override
  publicNode visit multiply and divide (multiply and divide Context Context) {expression node node =newExpression node ();intOperator = context. Operator. GetType (); Node. Operator = (operator == circle5Parser. T take the | | operator = =5Parser.T number times)? Operation symbol. Multiplication: operation symbol. In addition to; Left child = visit(context. Expressions (0)); Right child = visit(context. Expressions (1));
    returnNode; }}Copy the code

A slightly more complex “expression” node in the syntax tree, with redundant code:

public classExpression nodeextendsnode{

  publicOperation symbol Operator;@Override
  publicObject evaluate () {ifOperator. Equals (operator symbol. Plus)) {return (int)(left child. Evaluate ()) + ((int) right child node. Evaluate (); }else ifOperator. Equals (operator symbol. Reduction)) {return (int)(left child node. Evaluate ()) - (int) right child node. Evaluate (); }else ifOperator. Equals (operator symbol. X)) {return (int)(left child node. Evaluate ()) * (int) right child node. Evaluate (); }else ifOperator. Equals (operator symbol. In addition to)) {return (int)(left child node. Evaluate ())/(int) right child node. Evaluate (); }else {
      return null; }}}Copy the code

Having already run ten test files manually, we now need to add tests and functionality in addition to cleaning up the code.

2018-01-11