antlr-设计基本语法

Deriving Grammars from Language Samples

Grammars包括一个名字,和互相调用的语法

grammar MyG;
rule1 : «stuff» ;
rule2 : «more stuff» ;
...

需要指明«stuff»内容是什么,我们需要哪些规则,哪个是开始规则;
我们需要自顶向下,设计语法的细致结构,编码具体的规则;
右侧是其他token或者已经定义的;
csv

file : «sequence of rows that are terminated by newlines» ;
row : «sequence of fields separated by commas» ;
field : «number or string» ;

语言通用模式

Sequence

USER parrt
PASS secret
RETR 1
retr : 'RETR' INT '\n' ; // match keyword integer newline sequence

csv文件

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

在java中识别语句

stats : (stat ';')* ; // match zero or more ';'-terminated statements

基本的调用argument

exprList : expr (',' expr)* ;

描述antlr自己的语法

**// match 'rule-name :' followed by at least one alternative followed
// by zero or more alternatives separated by '|' symbols followed by ';'
rule : ID ':' alternative ('|' alternative )* ';' ;**

Choice
使用|或者or代表选择
csv文件中

field : INT | STRING ;

类型

type: 'float' | 'int' | 'void' ; // user-defined types

语句

stmt: node_stmt
| edge_stmt
| attr_stmt
| id '=' id
| subgraph
;

Token Dependency

vector : '[' INT+ ']' ; // [1], [1 2], [1 2 3], ...
expr: expr '(' exprList? ')' // func call like f(), f(x), f(1,2)
| expr '[' expr ']' // array index like a[i], a[i][j]
...
;
functionDecl
: type ID '(' formalParameters? ')' block // "void f(int x) {...}"
;
formalParameters
: formalParameter (',' formalParameter)*
;
formalParameter
: type ID
;

json

object
: '{' pair (',' pair)* '}'
| '{' '}' // empty object
;
pair: STRING ':' value ;

Nested Phrase
嵌套规则

stat: 'while' '(' expr ')' stat // match WHILE statement
| '{' stat* '}' // match block of statements in curlies
... // and other kinds of statements
;

stat是循环语句,下面是间接回归

stat: 'while' '(' expr ')' stat // match WHILE statement
| block // match a block of statements
... // and other kinds of statements
;
block: '{' stat* '}' ; // match block of statements in curlies

很多语言有多个自递归

expr: ID '[' expr ']' // a[1], a[b[1]], a[(2*b[1])]
| '(' expr ')' // (1), (a[1]), (((1))), (2*a[1])
| INT // 1, 94117
;

核心语法标记

Syntax		 			Description
x 						Match token, rule reference, or subrule x.
x y ... z		 		Match a sequence of rule elements.
(... | ... | ...) 		Subrule with multiple alternatives.
x?					    Match x or skip it.
x* 						Match x zero or more times.
x+						Match x one or more times.
r : ... ;				Define rule r.
r : ... | ... | ... ;	Define rule r with multiple alternatives.

优先级、左递归、结合性

算数表达式

expr : expr '*' expr // match subexpressions joined with '*' operator
| expr '+' expr // match subexpressions joined with '+' operator
| INT // matches simple integer atom
;

这个例子对于1+2*3有多重理解

在具有幂运算的表达式中,把^放前面,因为它的优先级更高

expr : expr '^'<assoc=right> expr // ^ operator is right associative
| expr '*' expr // match subexpressions joined with '*' operator
| expr '+' expr // match subexpressions joined with '+' operator
| INT // matches simple integer atom
;

识别通用词法结构

lexer大写
parser小写

Identifiers
非空的大小写字母

ID : ('a'..'z'|'A'..'Z')+ ; // match 1-or-more upper or lowercase letters

'a'..'z'代表a-z的任意字母
类似正则的方式

ID : [a-zA-Z]+ ; // match 1-or-more upper or lowercase letters

但是下面的例子中,关键字enum和for也会被匹配吗?

grammar KeywordTest;
enumDef : 'enum' '{' ... '}' ;
...
FOR : 'for' ;
...
ID : [a-zA-Z]+ ; // does NOT match 'enum' or 'for'

这里enum和for定义在ID之前,因此优先级比ID更高,会先匹配上;

Matching Numbers

INT : '0'..'9'+ ; // match 1 or more digits
INT : [0-9]+ ; // match 1 or more digits

浮点规则

FLOAT: DIGIT+ '.' DIGIT* // match 1. 39. 3.14159 etc...
| '.' DIGIT+ // match .1 .14159
;
fragment
DIGIT : [0-9] ; // match single digit

加上了fragment标记,这个DIGIT是被其他部分使用的,不能独立作为token

Matching String Literals
这里是由双引号扩起来的内容

STRING : '"' .*? '"' ; // match anything in "..."

加上?是非贪婪模式

STRING: '"' (ESC|.)*? '"' ;
fragment
ESC : '\\"' | '\\\\' ; // 2-char sequences \" and \\

把\和\包含进来;因为antlr自身也需要转义,所以需要多写一个;

Matching Comments and Whitespace
只需要跳过

LINE_COMMENT : '//' .*? '\r'? '\n' -> skip ; // Match "//" stuff '\n'
COMMENT : '/*' .*? '*/' -> skip ; // Match "/*" stuff "*/"

第一个一直匹配到//到换行之间的内容

WS : (' '|'\t'|'\r'|'\n')+ -> skip ; // match 1-or-more whitespace but discard
WS : [ \t\r\n]+ -> skip ; // match 1-or-more whitespace but discard

Drawing the Line Between Lexer and Parser

parser匹配换行
lexer不必识别结构

192.168.209.85 "GET /download/foo.html HTTP/1.0" 200
file : NL+ ; // parser rule matching newline (NL) sequence
STUFF : ~'\n'+ -> skip ; // match and discard anything but a '\n'
NL : '\n' ; // return NL to parser or other invoking code

匹配ip地址

file : row+ ; // parser rule matching rows of log file
row : ip STRING INT NL ; // match log file record
ip : INT '.' INT '.' INT '.' INT ; // match IPs in parser
INT : [0-9]+ ; // match IP octet or HTTP result code
STRING: '"' .*? '"' ; // matches the HTTP protocol command
NL : '\n' ; // match log file record terminator
WS : ' ' -> skip ; // ignore spaces
posted @ 2016-12-27 14:13  zhangshihai1232  阅读(704)  评论(0)    收藏  举报