1

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

我想要一棵可以用来评估上述表达式的树。所以我在 Antlr3 中用Antlr parser for and/or logic 中的示例尝试了这个 - 如何在逻辑运算符之间获取表达式?

它在 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);
}

get Children 方法如下。但这似乎并没有提取任何令牌。

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 编写解析器吗?

4

1 回答 1

3

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

and : not (AND not)*;

您最终将得到一AndContext棵树,其中分别包含和NotContext引用的TerminalNode子级。为了更容易使用树,将包含一个生成的方法,该方法返回由规则调用返回的上下文对象列表(返回类型)。它还包含一个生成的方法,该方法返回为每个匹配的令牌创建的实例列表。notANDAndContextnot()notList<? extends NotContext>ANDTerminalNodeAND

于 2013-03-22T20:50:46.430 回答