ANTLR学习(三)

ANTLR基本语法

前面已经简单介绍了ANTLR以及怎么安装和测试。
同学们应该大概清楚ANTLR的使用场景,但是对于关键步骤,怎么编写一个语法文件并没有详细介绍,这篇笔记主要详细讲解一下ANTLR的语法。

在过去的几十年内人类发明了很多种编程语言,现在还在持续增加。而ANTLR的语法就是要把任意的编程语言的语法规则通过自身的语法描述文件来定义。好消息是,这么多的编程语言,相对而言,基本的语言模式并不多。
之所以这样,其实原因也很简单。因为我们在设计编程语言时,倾向于将语言设计的和脑海中的自然语言相类似。我们期望看到有序的词法符号,也期望同词法符号的依赖关系。比如不会有任何语言出现{(})这种语法,大家会用数学符号,标识符,字符串。

总结下来,所有编程语言的语言模式可以抽象成四类:

  • 序列:一列元素,类似数组里面的值
  • 选择:在多种可选方案中做选择,eg:if else
  • 词法符号依赖:符号是成对出现,eg:左右括号
  • 嵌套结构: 自相似的语言结构,eg:编程语言中的一个语法嵌套另一个语法。

ANTLR实际就是基于以上的原则进行语法的设计,达到定义一种语法的作用。下面我们一个个详细说明一下这四种语言模式

序列

序列模式是最常见的一种模式。简单来说把一连串的词法按顺序排列就是一种序列,所有的指令也是一个序列。

然后ANTLR结合正则表达式,就可以快速的描述出多个元素的序列模式,
INT+表示一个或多个整数,INT*表示零或多个整数,INT?表示零个或一个整数。
CSV这个文件为例,CSV的语法用ANTLR描述出来就是

file : (row '\n')*; //一个‘\n’作为终止符的序列,表示文件由多行组成
row  : field (',' field)*; //一个‘,’作为分隔符的序列,文件每行由多个字段组成, 这里其实也用到了嵌套模式
field : STRING; // 假设字段都是字符串

选择

如果一个编程语言只有一种语句,就太无聊了,也做不了什么。选择模式就是表示一个地方可能支持多种有效的语句。
在ANTLR中使用|来表达选择模式,选择模式在语法中随处可见。
上面的例子,CSV的字段肯定不一定都是字符串,那么我们应该改成

field : STRING | INT;

注意的是在ANTLR中是按顺序来匹配解析规则,所以多个|分割的规则顺序是有意义的。

词法符号依赖

词法符号依赖最常见的用法还是定义括号的限制,规定括号必须成对出现。
还是那上面的字段举例子,比如我们要限制CSV的字段必须用“包括。那可以改成

field : ‘“’ STRING | INT ‘”’;

嵌套结构

嵌套词组是一种自相似的语言结构,即它的子词组也遵循相同的规则。表达式是一种典型的自相似语言结构,它包含多个嵌套的,以运算符分割的子表达式。类似于我们程序中的递归。
我们看一下简单wihle循环怎么定义

stat : 'while' '(' expr ')' stat //匹配wihle语句,必须开头是while
     | '{' stat* '}'             //匹配while里面的多条语句,这里的关键是stat里面的子语句也是stat词法,就形成了一个嵌套。
     ...
     ;

其实上面这种直接递归是比较难理解,一般的写法会写成间接递归

stat : 'while' '(' expr ')' stat
     | '{' block* '}'            
     ...
     ;
block : '{' stat* '}'

常用语法

前面已经介绍了常用的四种语法模式,下面列一下ANTLR常用的语法标记,后面可以当作写语法文件的字典。

用法 描述
X 匹配元素
x y ... z 匹配一系列多个的元素
(...|...|...) 一个具有多个选择分支的元素
x? 匹配零或一个X元素
x* 匹配零或多个X元素
x+ 匹配一或多个X元素
r : ...; 定义一个新规则r
r : ...|...|...; 定义一个多个分支的新规则r
模式名 描述
序列 x y ... z
带终止符的序列 (statement ';')*
带分隔符的序列 expr (',' expr)*
选择 field : STRING INT;
词法符号依赖 '(' expr ')'
嵌套 expr : '(' expr ')' | ID;

JSON的语法

下面通过分析一下大家常用的json的语法来加强理解。

json
   : value
   ;
obj
   : '{' pair (',' pair)* '}'
   | '{' '}'
   ;
pair
   : STRING ':' value
   ;
arr
   : '[' value (',' value)* ']'
   | '[' ']'
   ;
value
   : STRING
   | NUMBER
   | obj
   | arr
   | 'true'
   | 'false'
   | 'null'
   ;

上面是json格式最核心的语法定义,回顾一下,这里其实用到了前面说的全部四种模式,下面一一讲解。

json
   : value
   ;

这里其实是定义了一个json的基础,json基础规则就由一个value规则组成。

value
   : STRING
   | NUMBER
   | obj
   | arr
   | 'true'
   | 'false'
   | 'null'
   ;

然后这里定义了value的规则, 可以看到这里用到了选择模式。 json的value可以是字符串,数字,true,false,null, 这四个其实是传统定义json格式“值”部分能够使用的基本类型。然后除了基本类型,value还可以是obj和arr。

arr
   : '[' value (',' value)* ']'
   | '[' ']'
   ;

arr这个规则其实就是一个json数组,它由多个value通过,分割的数组,或者是一个空数组。 这里用到了间接嵌套模式。 统通过这个规则,json的某一个值可以是另一组json格式

obj
   : '{' pair (',' pair)* '}'
   | '{' '}'
   ;
pair
   : STRING ':' value
   ;

obj是由一个json对象,它由多个pair通过,分割。或者可以是一个空的{}。然后其中的pair则是一个最基础的key-val的格式,这也是json最基础的语法。可以看出一点json定义中key必须是字符串。

这里其实就是json最核心的一些定义,大家可以回想一下json格式的规则是不是就是这样的。然后再加上一下针对不同格式的正则要求,就完成了json的ANTLR语法定义。下面附带了完整的文件,有兴趣可以自己结合之前的分享,读一下这文件。

JSON的ANTLR语法文件

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 227,022评论 6 528
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 97,760评论 3 412
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 174,687评论 0 373
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 62,318评论 1 307
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 71,112评论 6 405
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 54,645评论 1 320
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 42,724评论 3 435
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 41,885评论 0 285
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 48,387评论 1 330
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 40,368评论 3 354
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 42,506评论 1 365
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 38,063评论 5 355
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 43,759评论 3 343
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 34,150评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 35,414评论 1 281
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 51,080评论 3 386
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 47,494评论 2 370

推荐阅读更多精彩内容

  • Antlr简介 ANTLR 语言识别的一个工具 (ANother Tool for Language Recogn...
    谢谢侬侬侬阅读 6,345评论 0 2
  • 前言 这篇文章是为了让新手能够快速全面的上手学习 ANTLR 的词法,语法解析原理以及其特性。因为自己在学习的过程...
    司鑫阅读 1,339评论 0 0
  • 最近科研项目需要加入一些新东西,需要我构建一个程序信息库,然后就想设计一套类似sql的查询语言去查询库里包含的内容...
    yufeiyang1995阅读 5,905评论 0 3
  • 翻译:原文语法本质上是一个语法声明,后面是规则列表,但具有以下一般形式: 包含语法X的文件名必须称为X.g4。您可...
    威尔士的海阅读 928评论 0 0
  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 4,414评论 0 5