【编译原理】Antlr 入门使用

打印 上一主题 下一主题

主题 878|帖子 878|积分 2634

前面文章我们学习了编译器前端的词法和语法分析工具,本篇我们来看看如何借助 Antlr 工具,快速生成词法和语法分析代码。
一、安装

mac 环境:
1)安装
  1. brew install antlr
复制代码
2)设置 classpath
(把 Antlr 的 JAR 文件设置到 CLASSPATH 环境变量中,以便顺遂编译所生成的 Java 源代码。)
  1. vi ~/.bash_profile
  2. # 替换成你的 antlr jar 路径
  3. CLASSPATH=".:/opt/homebrew/Cellar/antlr/4.13.1/antlr-4.13.1-complete.jar:$CLASSPATH"
  4. source ~/.bash_profile
复制代码
有了这个玩意,你可以用很简单的方式定义好词法和语法文件,他会主动生成对应的解析文件,给你生成出 AST 来。
你可以从生成的类文件中,看看是如何生成 AST 树的。
对于我们之前遇到的左递归问题,它又是如何办理的,也是用循环代替递归么?
生成 AST 树,算完成了词法分析和语法分析。
根据这棵树做什么,就是语义分析了。
二、开发 Java 项目

1、创建一个 maven 项目
2、pom 中添加 Antlr 库
  1.         <dependency>
  2.             <groupId>org.antlr</groupId>
  3.             <artifactId>antlr4-runtime</artifactId>
  4.             <version>4.10</version>
  5.         </dependency>
复制代码
3、编写一个 antlr 文件 Expr.g4。位置随意,可以放到 src 目录
  1. grammar Expr;
  2. expr: expr op=(ADD|SUB) expr      # AddSub
  3. | INT                             # int
  4. ;
  5. ADD: '+';
  6. SUB: '-';
  7. INT : [0-9]+ ;
  8. WS : [ \t]+ -> skip;
复制代码
4、编译项目 (如许可以生成一些antlr的解析器的类代码,方便后面编程)
  1. mvn compile
复制代码
你应该能在项目根目录看到一个 gen 文件夹,打开后内里是生成的 java 类

把这部分代码放到你的 src 包路径下 src/main/java/com/xxx/my_antlr_demo/antlr4
5、编写调用代码
EvalVisitor.java
  1. import com.shuofxz.my_antlr_demo.antlr4.ExprBaseVisitor;
  2. import com.shuofxz.my_antlr_demo.antlr4.ExprLexer;
  3. import com.shuofxz.my_antlr_demo.antlr4.ExprParser;
  4. public class EvalVisitor extends ExprBaseVisitor<Integer> {
  5.     @Override
  6.     public Integer visitAddSub(ExprParser.AddSubContext ctx) {
  7.         Integer left = visit(ctx.expr(0));  // should call "visit", not "visitChildren"
  8.         Integer right = visit(ctx.expr(1));
  9.         if (ctx.op.getType() == ExprLexer.ADD) {
  10.             return left + right;
  11.         } else {
  12.             return left - right;
  13.         }
  14.     }
  15.     @Override
  16.     public Integer visitInt(ExprParser.IntContext ctx) {
  17.         return Integer.valueOf(ctx.INT().getText());
  18.     }
  19. }
复制代码
AppDemo.java
  1. import com.shuofxz.my_antlr_demo.antlr4.ExprLexer;
  2. import com.shuofxz.my_antlr_demo.antlr4.ExprParser;
  3. import org.antlr.v4.runtime.CharStreams;
  4. import org.antlr.v4.runtime.CodePointCharStream;
  5. import org.antlr.v4.runtime.CommonTokenStream;
  6. import org.antlr.v4.runtime.tree.ParseTree;
  7. public class AppDemo {
  8.     public static void main(String[] args) {
  9.         String input = null;
  10.         // 此处把输入的参数,直接赋值了
  11.         args = new String[2];
  12.         args[0] = "-input";
  13.         args[1] = "1+2+3-4";
  14.         for (int i=0; i<args.length; i++) {
  15.             if (args[i].equals("-input")) {
  16.                 input = args[++i];
  17.             }
  18.         }
  19.         if (input == null) {
  20.             System.out.println("args:  -input <expression>");
  21.             return;
  22.         }
  23.         CodePointCharStream charStream = CharStreams.fromString(input);
  24.         ExprLexer lexer = new ExprLexer(charStream);
  25.         CommonTokenStream tokens = new CommonTokenStream(lexer);
  26.         ExprParser parser = new ExprParser(tokens);
  27.         ParseTree tree = parser.expr();
  28.         EvalVisitor visitor = new EvalVisitor();
  29.         Object result = visitor.visit(tree);
  30.         System.out.println("output=" + result);
  31.     }
  32. }
复制代码
记得重新实行第四步生成代码并更换。
然后我们可以把输入字符换为 1@2@3#4。
你大概猜到了这里就实现了类似操作符重载的功能。
那么后面我们就可以用这个工具,实现我们自己的语法解析工具了。
三、Antlr 中都做了什么?

antlr 语法文件中写的都是啥?

  • 分为两个部分:词法规则和语法规则
  • 词法规则定义了语言的基本词汇元素,即词法单位(Tokens)。它们通常包括标识符、常量、关键字和符号等。通常以大写字母开头,如 ADD、INT 等
  • 语法规则定义了语言的结构,阐明了不同词法单位是如何组合起来形成语言结构的。语法规则描述了语句、表达式、声明等高级结构,如 expr。
接下来我们表明一下关键实行步骤中都做了什么事情:
  1. grammar Expr;
  2. expr: expr op=(ADD|SUB) expr      # AddSub
  3. | INT                             # int
  4. ;
  5. ADD: '@';
  6. SUB: '#';
  7. INT : [0-9]+ ;
  8. WS : [ \t]+ -> skip;
复制代码

  • 词法分析器:词法分析的任务是将输入文本分割成一系列的记号(tokens),每个记号是语言中最小的故意义单位,如关键字、标识符、字面量等。
  • 记号流:用于从词法分析器中获取记号,并将它们组织成一个流,以便之后进行语法分析。
  • 语法分析器:对记号流tokens进行语法分析。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

不到断气不罢休

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表