Antlr的语法学习

Antlr的语法学习

一个例子

grammar Hello;
r: 'hello' ID ;               // 匹配关键字 hello,然后再匹配一个标识
ID: [a-z]+ ;                  // 标识由小写字母组成
WS: [ \t\r\n]+ -> skip ; // 忽略空白、制表符,换行

这个语法的解析器,可以接受像 "hello ant" 或者 "hello bee" 这样的句子,但 "hi ant"或者"hello Ant"就不行。因为 “hi” 无法和 “hello” 匹配,“Ant” 中有大写字母和 ID 无法匹配。
当解析器接受了 "hello ant"后,将会得到这样的ast结构:

r
  hello
  ant

语法结构

从上面可以看出,语法结构最基本的部分是一个grammar ...加上几条... : ... ;
grammar ... 称为语法声明,说明语法的名字。... : ... ; 称为规则,说明该语法的解析器要怎么做。
一个包含所有结构的语法文件是这个样子:

gammar ... ;
options {...}
import ... ;

tokens {...}
channels {...} // 仅用于词法解析器
@...{...}
...
... : ... ;
...

options 说明选项,后面细说。先说import。

引入语法

当一个语法A是是对另一个语法B的少量改动时,可以用引入语法,比如语法A定义了整数的加法运算:

grammar A;
expr : item ( '+' item) *;
item:  INT ;
INT: [0-9]+ ;
WS: [ \r\t\n]+ -> skip ;

如果语法B只是需要让item可以是表示变量的标识符,那么可以引入语法A,并重定义item就可以了:

grammar B;
import A;
item : ID ;
ID : [a-z]+ ;

在引入多个语法的时候,如果存在相同名称的规则,以最先引入的为准。如果存在嵌套,嵌套最深的最先引入。

Tokens部分

tokens用于定义标识符的类型:

tokens { Token_1, ... , Token_n }

多数时候用于定义从外部程序传递来的标识符。

语法层次的动作

语法层次的动作相对于规则层次的动作。用于在规则之外定义一些动作。目前有两个:@header, @members

grammar Count;
@header {
	package foo;
}
@members {
	int count = 0;
}
list
@after { System.out.println(count + " ints"); }
	: INT { count++; } (',' INT {count++; } )*
	;
INT: [0-9]+ ;
WS: [ \r\t\n]+ -> skip ;	

这个语法在接受了"10, 9, 8, 7"这个输入后,会输出4 ints

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值