对于一门计算机语言的语法,有4种基本的抽象语言模式:
接下来就介绍一下Antlr如何表达这些模式
retr : 'RETR' INT '\n'
可匹配 “RETR 整数 换行符” 这样的序列。file : (row '\n')*; // 以一个'\n'作为终止符的序列
row : field (',' field)* ; // 以一个','作为分隔符的序列
field: INT; // 假设字段都是整数
使用 | 符号作为或者来表达编程语言中的选择模式。
例1 : field : INT | STRING
例2 :
stmt : node_stmt
| edge_stmt
| attr_stmt
| id '=' id
;
使用一个序列来指明所有配对的符号,通常这些符号会把其他元素分组或者包裹起来。
例1: vector : '[' INT+ ']' ;
例2: expr : expr '(' exprList? ')';
例3: object : '{' pair (',' pair)* '}';
嵌套的词组是一种自相似的语言结构,即子词组遵循相同的结构。
例1:
stat: 'while' '(' expr ')' stat
| '{' stat* '}'
...
;
以上语句中 stat 是一个循环结构,可以是一个语句或者由花括号包裹的一组语句。
expr : expr '*' expr
| expr '+' expr
| INT
;
对于 1+23 这样的输入文本而言,有 1 + (23) 和 (1+2) * 3 两种理解。
ANTLR通过优先选择位置靠前的备选分支来解决歧义问题,隐式地允许我们指定运算符优先级。
expr : expr '^'<assoc=right> expr
| INT
;
expr : expo
| ...
;
expo : expr '^'<assoc=right> expr ;
ANTLR允许词法规则和语法规则在同一个语法文件中,但是这是语言识别过程中的两个不同阶段,我们必须告诉ANTLR每条规则对应的阶段。方式: 词法规则以大写字母开头,语法规则以小写字母开头。
常见词法符号的词法规则:
ID : ('A'..'Z'|'a'..'z')+;
ID : [A-Za-z]+;
enumDef : 'enum' '{' ... '}';
...
ID : [a-zA-Z]+;
FLOAT : DIGIT+'.'DIGIT*
| '.'DIGIT+
;
fragment
DIGIT : [0-9] ;
将一条规则声明为fragment是说明改规则本身不是一个词法符号,只会被其他的词法规则使用,即不能在文法规则中引用。
STRING: '"' (ESC|.)*? '"';
fragment
ESC : '\\"' | '\\\\' ;
LINE_COMMENT : '//' .*? '\r'?'\n' -> skip ;
COMMENT : '/*' .*? '*/' -> skip ;
大多编程语言把空白字符当成词法符号间的分隔符,并可以将它们忽略,丢弃空白符的ANTLR语法如下:
WS : (' '|'\t'|'\r'|'\n')+ -> skip ;
或者
WS : [ \t\r\n]+ -> skip;
以上内容主要对ANTLR常见的一些语法进行了说明,后续会对更细节的语法进行说明
因篇幅问题不能全部显示,请点此查看更多更全内容