一.语法说明:
一般我们解析语言分为,词法解析和语法解析
词法解析根据用户输入生成一系列token序列(即关键字,操作数,操作方法等的列表)
语法解析根据token生成语法树(这里就是根据编写的g4 文件生成对应的树状结构及树状结构的值)
二.g4说明
1.antlr4 分为词法规则和文法规则
文法(语法)规则一般对应非叶子节点(文法规则有小写字母组成)
词法一般对应叶子节点(词法规则一般以大写字母组成)
2.为了避免歧义antlr4定义了一套匹配规则
文法规则优先词法规则
字符串常量属于词法规则
字符串常量优先其他的词法规则
相同优先级采用自上而下匹配即按申明顺序优先匹配
3.最左匹配原则
如果如下g4语法
expr: expr op=('*'|'/') expr # MulDiv
| expr op=('+'|'-') expr # AddSub
| INT # int
| '(' expr ')' # parens
INT : [0-9]+ ;
则1+2*3可以解析为 如下两种
expr(1)+exp(2*3)
和exp(1+2)*exp(3)
Antlr4 是怎样解决如上歧义的呢
是根据申明匹配位置(即优先匹配最左)
expr: expr op=('*'|'/') expr # MulDiv
| expr op=('+'|'-') expr # AddSub
| INT # int
| ID # id
| '(' expr ')' # parens
;
我们看到 expr op=('*'|'/') expr 是在expr op=('+'|'-') expr 的前面(即左边)
所以语法解析为expr(1)+exp(2*3)
如果换成
expr op=('+'|'-') expr # AddSub
|expr: expr op=('*'|'/') expr # MulDiv
| INT # int
| ID # id
| '(' expr ')' # parens
则·会·匹配exp(1+2)*exp(3)
4.常用的语法结构
1.序列(一列元素)
outExpressionseq:outExpression(','outExpression)*;
2.选择(在多种可选方案中作出选择)
booleanExpression:inExpression #inboolean
|comparison #normalboolean
|'(' booleanExpression ')' #priorityboolean
|left=booleanExpression (operator=AND)? right=booleanExpression #andboolen
|left=booleanExpression operator=OR right=booleanExpression #orboolean;
3.词法符号依赖(一个词法符号需要和某出另外一个词法符号配对,如左右括号)
funciton:identifier'('paramterSeq')';
4.镶嵌结构(一种字相似的语言结构)
expr: expr op=('*'|'/') expr # MulDiv #语法expr可以如下表示
| expr op=('+'|'-') expr # AddSub
| INT # int
| ID # id
| '(' expr ')' # parens
;
5错误监听机制
分为词法错误和语法错误
实现ANTLRErrorListener接口重写syntaxError()方法
通过观察着模式实现
SplLexer lexer = new SplLexer(input);
lexer.addErrorListener(new SplLexErrorListener());
SplParser parser = new SplParser(tokens);
parser.addErrorListener(new SplErrorListener());
这个时目前antlr默认的实现策略
重写错误策略
protected ANTLRErrorStrategy _errHandler = new DefaultErrorStrategy();
6.访问着模式
通过生成代码时加入 -visitor 生成访问着模式代码(通过继承SplBaseVisitor 重写相应的代码一般为叶子节点代码)
public class SplQueryVisitor extends SplBaseVisitor<Expression>