如果您被允许使用像 ANTLR 这样的解析器生成器工具,那么您可以从这里开始。简单逻辑语言的语法可能如下所示:
grammar Logic;
parse
: expression EOF
;
expression
: implication
;
implication
: or ('->' or)*
;
or
: and ('||' and)*
;
and
: not ('&&' not)*
;
not
: '~' atom
| atom
;
atom
: ID
| '(' expression ')'
;
ID : ('a'..'z' | 'A'..'Z')+;
Space : (' ' | '\t' | '\r' | '\n')+ {$channel=HIDDEN;};
但是,如果您像(P || Q || R) && ((P -> R) -> Q)
使用从上述语法生成的解析器一样解析输入,则解析树将包含括号(解析表达式后您不感兴趣的东西)并且运算符不会是每个子的根 -树,如果您对评估表达式感兴趣,这不会让您的生活变得更轻松。
您需要告诉 ANTLR 从 AST 中省略某些标记(这可以通过在标记/规则!
之后放置一个来完成)并使某些标记/规则成为它们(子)树的根(这可以通过放置一个^
之后)。最后,您需要在options
语法部分中指出您希望创建正确的 AST 而不是简单的解析树。
所以,上面的语法看起来像这样:
// save it in a file called Logic.g
grammar Logic;
options {
output=AST;
}
// parser/production rules start with a lower case letter
parse
: expression EOF! // omit the EOF token
;
expression
: implication
;
implication
: or ('->'^ or)* // make `->` the root
;
or
: and ('||'^ and)* // make `||` the root
;
and
: not ('&&'^ not)* // make `&&` the root
;
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')+;
Space : (' ' | '\t' | '\r' | '\n')+ {$channel=HIDDEN;};
您可以使用以下类测试解析器:
import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
import org.antlr.stringtemplate.*;
public class Main {
public static void main(String[] args) throws Exception {
// the expression
String src = "(P || Q || R) && ((P -> R) -> Q)";
// create a lexer & parser
LogicLexer lexer = new LogicLexer(new ANTLRStringStream(src));
LogicParser parser = new LogicParser(new CommonTokenStream(lexer));
// invoke the entry point of the parser (the parse() method) and get the AST
CommonTree tree = (CommonTree)parser.parse().getTree();
// print the DOT representation of the AST
DOTTreeGenerator gen = new DOTTreeGenerator();
StringTemplate st = gen.toDOT(tree);
System.out.println(st);
}
}
现在要运行Main
课程,请执行以下操作:
*尼克斯/MacOS
java -cp antlr-3.3.jar org.antlr.Tool Logic.g
javac -cp antlr-3.3.jar *.java
java -cp .:antlr-3.3.jar 主要
视窗
java -cp antlr-3.3.jar org.antlr.Tool Logic.g
javac -cp antlr-3.3.jar *.java
java -cp .;antlr-3.3.jar 主要
这将打印以下 AST的DOT 源:

(使用graphviz-dev.appspot.com生成的图像)
现在您需要做的就是评估这个 AST !:)