ANTLR教程(三)语法分析

本文介绍ANTLR语法解析器的基础知识,包括文法产生式的四种模式:顺序、选择、记号依赖和递归模式,并演示如何使用ANTLR生成语法树及进行代码转换。

文法产生式

基于四种模式实现文法产生式

顺序模式

(INT)+
file : (row ‘\n’)* ; */ sequence with a ‘\n’ terminator
row : field (‘,’ field)* ; /* sequence with a ‘,’ separator
field: INT ; // assume fields are just integers

选择模式

field : INT | STRING ;

记号依赖

出现成对终结符级即可
expr: expr ‘(’ exprList? ‘)’ // func call like f(), f(x), f(1,2)

expr ‘[’ expr ‘]’ // array index like a[i], a[i][j]


;

递归模式

消除产生式歧义

定义符号结合性

expr : expr ‘^’

定义符号优先级

antlr 实际语言例子

csv 主要顺序模式

这里写图片描述

json 主要递归模式

这里写图片描述

使用antlr显示语法树方法

  1. 显示解析到的每个token信息
  2. 显示lisp形式语法
  3. 图形形式语法树
    产生式非终结符上右键 -》 Test rule 非终结符 -》在弹出的窗口输入产生式

使用antlr实现语法解析,生成语法树AST

antlr生的语法树相关的数据结构

这里写图片描述
xxxContext数据结构记录了每个文法产生式左边非终结符的信息,通过相应的方法可以获得每个文法产生式右边元素的值
例如:
AssignContext->ID()和->expr()

antlr编译语法文件后自动生成的类

这里写图片描述

  • 词法分析类——ArrayInitLexer.java
  • 词法分析的结果——记号流ArrayInit.tokens
    对每一个 token赋值一个 token数字

  • 语法分析类——ArrayInitParser.java
    每条文法规则的处理方法

  • 语法树遍历操作类——ArrayInitListener.java, ArrayInitBaseListener.java

将antlr生成的类集成起来解析语法,实现应用

打印语法树

// import ANTLR's runtime libraries
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;
public class Test {
public static void main(String[] args) throws Exception {
// create a CharStream that reads from standard input
ANTLRInputStream input = new ANTLRInputStream(System.in);
// create a lexer that feeds off of input CharStream
ArrayInitLexer lexer = new ArrayInitLexer(input);
// create a buffer of tokens pulled from the lexer
CommonTokenStream tokens = new CommonTokenStream(lexer);
// create a parser that feeds off the tokens buffer
ArrayInitParser parser = new ArrayInitParser(tokens);
ParseTree tree = parser.init(); // begin parsing at init rule
System.out.println(tree.toStringTree(parser)); // print LISP-style tree
}
}

代码生成

starter/Translate.java
// import ANTLR's runtime libraries
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;
public class Translate {
public static void main(String[] args) throws Exception {
// create a CharStream that reads from standard input
ANTLRInputStream input = new ANTLRInputStream(System.in);
// create a lexer that feeds off of input CharStream
ArrayInitLexer lexer = new ArrayInitLexer(input);
// create a buffer of tokens pulled from the lexer
CommonTokenStream tokens = new CommonTokenStream(lexer);
// create a parser that feeds off the tokens buffer
ArrayInitParser parser = new ArrayInitParser(tokens);
ParseTree tree = parser.init(); // begin parsing at init rule
 // Create a generic parse tree walker that can trigger callbacks
 ParseTreeWalker walker = new ParseTreeWalker();
 // Walk the tree created during the parse, trigger callbacks
 walker.walk(new ShortToUnicodeString(), tree);
 System.out.println(); // print a \n after translation
}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值