| ANTLR 是用JAVA写的语言识别工具,它用来声明语言的语法,简称为“元语言”。 Idea中配置使用 pom.xml添加         <dependency>
            <groupId>org.antlr</groupId>
            <artifactId>antlr4-runtime</artifactId>
            <version>4.7</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>
 Idea setting中安装ANTLR插件(我本机安装完了)? ?Eclipse也类似的安装插件 
 ?示例:计算机四则计算(官网照抄) 1、新建g4文件,如Math.g4 grammar Math;
prog : stat+;
stat: expr NEWLINE          # printExpr
    | ID '=' expr NEWLINE   # assign
    | NEWLINE               # blank
    ;
expr:  expr op=('*'|'/') expr   # MulDiv
| expr op=('+'|'-') expr        # AddSub
| INT                           # int
| ID                            # id
| '(' expr ')'                  # parens
;
MUL : '*' ; // assigns token name to '*' used above in grammar
DIV : '/' ;
ADD : '+' ;
SUB : '-' ;
ID : [a-zA-Z]+ ;
INT : [0-9]+ ;
NEWLINE:'\r'? '\n' ;
WS : [ \t]+ -> skip;
 ?Idea 安装完ANTLR插件 右键g4文件可以看到,点击Configure ANTLR... 
 配置目录如下,按照你们自己的目录设置,点击OK 
 ?右键Math.g4文件,点击Generate ANTLR Recognizer 
 自动生成代码: 
 编写实现类,继承上面自动生成的类MathBaseVisitor,实现计算 public class MathVisitorImp extends MathBaseVisitor<Integer> {
    // 存储变量的值
    private Map<String, Integer> variable;
    public MathVisitorImp() {
        variable = new HashMap<>();
    }
    // 当遇到printExpr节点,计算出exrp的值,然后打印出来
    @Override
    public Integer visitPrintExpr(MathParser.PrintExprContext ctx) {
        Integer result  = ctx.expr().accept(this);
        System.out.println(result);
        return null;
    }
    // 分别获取子节点expr的值,然后做加减运算
    @Override
    public Integer visitAddSub(MathParser.AddSubContext ctx) {
        Integer param1 = ctx.expr(0).accept(this);
        Integer param2 = ctx.expr(1).accept(this);
        if (ctx.op.getType() == MathParser.ADD) {
            return param1 + param2;
        }else {
            return param1 - param2;
        }
    }
    // 分别获取子节点expr的值,然后做乘除运算
    @Override
    public Integer visitMulDiv(MathParser.MulDivContext ctx) {
        Integer param1 = ctx.expr(0).accept(this);
        Integer param2 = ctx.expr(1).accept(this);
        if (ctx.op.getType() == MathParser.MUL) {
            return param1 * param2;
        }else {
            return param1 / param2;
        }
    }
    // 当遇到int节点,直接返回数据
    @Override
    public Integer visitInt(MathParser.IntContext ctx) {
        return Integer.parseInt(ctx.getText());
    }
    // 当遇到Id节点,从变量表获取值
    @Override
    public Integer visitId(MathParser.IdContext ctx) {
        return variable.get(ctx.getText());
    }
    // 当遇到赋值语句,获取右边expr的值,然后将变量的值保存到variable集合
    @Override
    public Integer visitAssign(MathParser.AssignContext ctx) {
        String name = ctx.ID().getText();
        Integer value = ctx.expr().accept(this);
        variable.put(name, value);
        return null;
    }
}
 测试: public class MathVisitorTest {
    public static void exec(String input) {
        MathLexer lexer = new MathLexer(CharStreams.fromString(input));
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        MathParser parser = new MathParser(tokens);
        parser.setBuildParseTree(true);
        ParseTree root = parser.prog();
        MathBaseVisitor<Integer> visitor = new MathVisitorImp();
        root.accept(visitor);
    }
    public static void main(String[] args) {
        String input = "1+2+3+5-7+1\n";
//        String input = "a = 14\n" +
//                "b = a - 3\n" +
//                "a + b\n";
        exec(input);
    }
}
 结果输出为:5 g4检查语法是否通过 1.新建g4Test.txt内容如下 a=3
b=4
c=a+b
d=a+b+c
e=4**2
f=d+e
 2.测试g4是否通过 public class g4Main {
    public static void main(String[] args) throws Exception {
        CharStream inputStream = CharStreams.fromFileName("D:\\g4\\g4Test.txt", Charset.forName("UTF-8"));
        MathLexer lexer = new MathLexer(inputStream);
        CommonTokenStream token=new CommonTokenStream(lexer);
        MathParser parser=new MathParser(token);
        MathParser.ProgContext tree = parser.prog();
        tree.accept(new MathBaseVisitor<Object>(){
            @Override
            public Object visitPrintExpr(MathParser.PrintExprContext ctx) {
                return super.visitPrintExpr(ctx);
            }
        });
        System.out.println("g4执行结束");
    }
}
 结果输出为: line 5:4 extraneous input '*' expecting {'(', ID, INT}
g4执行结束
 line 5:4? 这是第5行第4列有语法不匹配的情况。 正常去修改Math.g4文件。以匹配语法。 后续会继续补充... |