CSharp使用ANTLR4生成簡單計算Parser

ANTLR簡介

ANTLR (ANother Tool for Language Recognition) is a powerful parser generator for reading, processing, executing, or translating structured text or binary files. It’s widely used to build languages, tools, and frameworks. From a grammar, ANTLR generates a parser that can build parse trees and also generates a listener interface (or visitor) that makes it easy to respond to the recognition of phrases of interest.

ANTLR(ANother Tool for Language Recognition)是一個強大的生成Parser的工具,用來讀取,處理,執行或者翻譯結構文本或二進位文件。ANTLR將從grammar生成一個parser,可以構建parse tree 並且生成一個監聽介面(或者visitor),並使你更簡單的感受到短語識別的樂趣。

本例簡介

本例將使用ANTLR生成CSharp parser程式碼,對減乘除數學表達式進行Parse並執行。源碼直接下載吧,點這裡

準備環境

1.ANTLR是一個JAVA程式,所以需要JAVA環境,本例使用的是java version “1.8.0_181″。
2.下載ANTLR //www.antlr.org/download.html 本例使用Complete ANTLR 4.9.1 Java binaries jar

準備語法文件Simple.g4

grammar Simple;

calc: expr EOF;

expr
:BR_OPEN expr BR_CLOSE
|expr TIMES expr
|expr DIV expr
|expr PLUS expr
|expr MINUS expr
|number
;

number: NUMBER;

PLUS:   'plus'  | '+';
MINUS:  'minus' | '-';
TIMES:  'times' | '*';
DIV:    'div'   | '/';
![](//img2020.cnblogs.com/blog/803166/202102/803166-20210227232628613-1602253693.jpg)


NUMBER: '-'? [0-9]+;
BR_OPEN: '(';
BR_CLOSE: ')';

WS: [ \t\r\n]+ -> skip;

生成CSharp程式碼

命令行執行
java -jar antlr-4.9.1-complete.jar -Dlanguage=CSharp Simple.g4

將生成文件添加至CSharp Project

CSharp Project添加ANTLR runtime引用

Install-Package Antlr4.Runtime.Standard

執行讀取到的數學表達式

        private static int visit(SimpleParser.ExprContext context)
        {
            if (context.number() != null)
            { //Just a number
                return int.Parse(context.number().GetText());
            }
            else if (context.BR_CLOSE() != null)
            { //Expression between brackets
                return visit(context.expr(0));
            }
            else if (context.TIMES() != null)
            { //Expression * expression
                return visit(context.expr(0)) * visit(context.expr(1));
            }
            else if (context.DIV() != null)
            { //Expression / expression
                return visit(context.expr(0)) / visit(context.expr(1));
            }
            else if (context.PLUS() != null)
            { //Expression + expression
                return visit(context.expr(0)) + visit(context.expr(1));
            }
            else if (context.MINUS() != null)
            { //Expression - expression
                return visit(context.expr(0)) - visit(context.expr(1));
            }
            else
            {
                throw new Exception();
            }
        }

讀入輸入測試

            var input = "2 * 3";
            AntlrInputStream inputStream = new AntlrInputStream(input);

            SimpleLexer lexer = new SimpleLexer(inputStream);
            CommonTokenStream commonTokenStream = new CommonTokenStream(lexer);
            SimpleParser parser = new SimpleParser(commonTokenStream);

            var result = visit(parser.expr());
            Console.WriteLine($"input:{input},output:{result}");

尾聲

本例簡單介紹在CSharp中如何使用ANTLR生成一個Parser,感受了一波短語識別的樂趣,You feel me? 後續ANTLR詳細的玩法再給大家分享。

Reference

C# target for ANTLR 4
Antlr is Awesome

Tags: