xyfree 发表于 2009-12-29 15:26

删帖吧

本帖最后由 xyfree 于 2012-01-21 03:38 编辑

xyfree 发表于 2009-12-29 16:14

开始使用ANTLRWorks 编写词法规则

开始使用ANTLRWorks 编写词法规则

为了让大家能够对ANTLRWorks有全过程的了解,也为了推广一下自己的Cx语言,我就用Cx语言来做例子了。
因为Cx语言跟C/C++是非常相像的,
所以我一开始的时候,脑子中先有Cx程序代码的模样,
然后再从代码示例中在脑子中构想词语的意义,这样语法规则自然就出来了。

虽然从Terence Parr(ANTLR的作者)的布局来看,(我猜)他是先从语法规则着手,逐步下降到词法规则,但我觉得先从词法规则开始比较适合新手。
废话少说,先来两段Cx语言里面注释的词法规则。

-------------------------------------------------------------------
/* Cx代码中忽略不去理会的字符,空白,tab,换行
    不要在ANTLR中使用中文的注释。。有时候你可能会遇到莫名其妙的错误
*/

WHITESPACE
: (' ' | '\t' | '\n' | '\r'){ skip(); };

/*Cx中,块注释以两个连续的#开头,中间匹配0个或多个其他字符,直到遇见另外的连续两个#
*/

COMMENT
: '##' (.)* '##'{ skip(); };

/* Cx中行注释和在C++中的一样,中间匹配0个或多个 不是换行符的任意字符,直到遇到换行符结束行注释
    如果行注释是在程序的末尾,后面可以没有换行符
*/

LINE_COMMENT
: '//' ~('\n'|'\r')*('\r\n' | '\r' | '\n') { skip(); }
| '//' ~('\n'|'\r')* { skip(); }
;
--------------------------------------------------------------------

在ANTLR中规定,词法规则名必须要以大写字母开头,通常是全大写字母。
按照惯例,只有开头是大写字母的词法规则是 fragment Lexer Rule,这样的词法规则是不会出现在parse tree中的(就是说不可以成为独立的parse tree节点)
譬如下面的例子展示如何使用fragment Lexer rule 来简化词法规则的编写

--------------------------------------------------------------------

/*十进制数字,由0至9十种字符组成,因为0..9在任何字符编码中都是连续的,所以可以用“..”
   记得不要漏了单引号(双引号似乎也是可以的)
*/

fragment
DecimalDigit
: ('0'..'9');

//Cx语言里面的十进制数字面量参考了D语言里面的做法,允许使用下划线分隔开一个或多个数字串,具有更好的可读性

fragment
DecimalFragment
: DecimalDigit+( '_' DecimalDigit+)*;

//各种十进制整数的字面量,要用后缀来告诉编译器应该解释成什么样的基本类型
   
DECIMAL_UBYTE
: DecimalFragment ('ub'| 'UB');

DECIMAL_BYTE
: DecimalFragment ('b'| 'B');

DECIMAL_USHORT
: DecimalFragment ('us'| 'US');

DECIMAL_SHORT
: DecimalFragment ('s'| 'S');

DECIMAL_UINT
: DecimalFragment ('u'| 'U');

DECIMAL_INT
: DecimalFragment;

DECIMAL_LONG
: DecimalFragment ('l'| 'L');

DECIMAL_ULONG
: DecimalFragment ('ul'| 'UL');

--------------------------------------------------------------------


声明Cx语言的关键字


声明关键字通常比较简单,只需把整个关键字用引号括起来就可以了
这里有一个关于关键字词法规则的策略:
尽量不要在语法规则中出现单引号(也就是没有命名的词法规则),虽然这是可以的。
但是对于新手来说,因为自己对整个要编译的语言才概念并不是一下子就会很清晰,有时候你不得不更改关键字的规则。
如果语法规则中全是单引号,查找和替换你会觉得这是一个噩梦.....
所以尽量为词法字符编写词法规则。以下是Cx语言里面的词法规则的一些片段,没兴趣的可以忽略

---------------------------------------------------------------------

STATIC_KW
: 'static';

PUBLIC_KW
: 'public';

PROTECTED_KW
: 'protected';

PRIVATE_KW
: 'private';

DEFAULT_KW
: 'default';

// primitive pointers
CONSTRUCTOR_KW
: 'This';

DESTRUCTOR_KW
: '~This';

SELFREF_KW
: 'this';

THAT_KW
: 'that';

THERE_KW
: 'there';

NEW_KW
: 'new';

DELETE_KW
: 'delete';

SIZEOF_KW
: 'sizeof';

// flow control

IF_KW
: 'if';

ELSE_KW
: 'else';

SWITCH_KW
: 'switch';

CASE_KW
: 'case';

//中间省略很多很多多。。。

RBRACKET
: ']';

LBRACE
: '{';

RBRACE
: '}';

LTP
: '<#';

RTP
: '#>';

--------------------------------------------------------------

[ 本帖最后由 xyfree 于 2009-12-29 21:48 编辑 ]
页: [1]
查看完整版本: 删帖吧