ANTLR4:布尔表达式的解析器

时间:2013-03-22 20:40:37

标签: antlr4

我正在尝试解析以下类型的布尔表达式 B1 = p& A4 = p | A6 = p&(~A5 = c)

我想要一棵树,我可以用它来评估上面的表达式。所以我在Antlr3中使用Antlr parser for and/or logic - how to get expressions between logic operators?

中的示例尝试了这个

它在Antlr3中有效。现在我想为Antlr 4做同样的事情。我提出了下面的语法并编译。但是我在编写Java代码时遇到了麻烦。

Antlr4语法的开始

grammar TestAntlr4;

options {
  output = AST;
}

tokens { AND, OR, NOT }

  AND : '&';
  OR  : '|';
  NOT : '~';


// parser/production rules start with a lower case letter
parse
  :  expression EOF!    // omit the EOF token
  ;

expression
  :  or
  ;

or
  :  and (OR^ and)*    // make `||` the root
  ;

and
  :  not (AND^ not)*      // make `&&` the root
  ;

not
  :  NOT^ atom    // make `~` the root
  |  atom
  ;

atom
  :  ID
  |  '('! expression ')'!    // omit both `(` and `)`
  ;

// lexer/terminal rules start with an upper case letter
ID
  :
    (
    'a'..'z'
    | 'A'..'Z'
    | '0'..'9' | ' '
    | ('+'|'-'|'*'|'/'|'_')
    | '='
  )+ 
  ;

我编写了Java代码(下面的代码段),用于获取表达式“B1 = p& A4 = p | A6 = p&(~A5 = c)”的树。我期待&有孩子B1 = p和|。孩子|操作员将有孩子A4 = p和A6 = p&(~A5 = c)。等等。 这是Java代码,但我试图弄清楚如何获得树。我能够在Antlr 3中做到这一点。

Java代码

String src = "B1=p & A4=p | A6=p &(~A5=c)";
CharStream stream = (CharStream)(new ANTLRInputStream(src));
TestAntlr4Lexer lexer = new TestAntlr4Lexer(stream);
parser.setBuildParseTree(true);
ParserRuleContext tree = parser.parse();
tree.inspect(parser); 
if ( tree.children.size() > 0) {
    System.out.println(" **************");
    test.getChildren(tree, parser);
}

获取儿童方法如下。但这似乎没有提取任何令牌。

public void getChildren(ParseTree tree, TestAntlr4Parser parser ) {
   for (int i=0; i<tree.getChildCount(); i++){
       System.out.println(" Child i= " + i);
       System.out.println(" expression = <" + tree.toStringTree(parser) + ">");
       if ( tree.getChild(i).getChildCount() != 0 ) {
           this.getChildren(tree.getChild(i), parser);
       }
   }
}

有人可以帮我弄清楚如何用Java编写解析器吗?

1 个答案:

答案 0 :(得分:3)

在ANTLR 4中删除了output=AST选项,以及您在语法中使用的^!运算符。 ANTLR 4生成解析树而不是AST,因此规则生成的树的根是规则本身。例如,给出以下规则:

and : not (AND not)*;

您最终会得到一个包含AndContextNotContext子项的TerminalNode树,分别用于notAND个引用。为了更容易使用树,AndContext将包含一个生成的方法not(),它返回由not规则的调用返回的上下文对象列表(返回类型{{1 }})。它还包含一个生成的方法List<? extends NotContext>,该方法返回为匹配的每个AND令牌创建的TerminalNode个实例的列表。