【整理】antlr语法中的fragment

【背景】

在用antlrworks新建一个antlr v3的示例代码:

file new ctrl n

new document antlr 3 grammar g

just demo to show example code

其中有个fragment:

can see the fragment keyword

代码为:

grammar justDemo;

ID  :	('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
    ;

INT :	'0'..'9'+
    ;

FLOAT
    :   ('0'..'9')+ '.' ('0'..'9')* EXPONENT?
    |   '.' ('0'..'9')+ EXPONENT?
    |   ('0'..'9')+ EXPONENT
    ;

COMMENT
    :   '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
    |   '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
    ;

WS  :   ( ' '
        | '\t'
        | '\r'
        | '\n'
        ) {$channel=HIDDEN;}
    ;

STRING
    :  '"' ( ESC_SEQ | ~('\\'|'"') )* '"'
    ;

CHAR:  '\'' ( ESC_SEQ | ~('\''|'\\') ) '\''
    ;

fragment
EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;

fragment
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;

fragment
ESC_SEQ
    :   '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
    |   UNICODE_ESC
    |   OCTAL_ESC
    ;

fragment
OCTAL_ESC
    :   '\\' ('0'..'3') ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7')
    ;

fragment
UNICODE_ESC
    :   '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
    ;

想要搞懂对应的fragment的含义是啥。


1.参考:

Antlr 中 fragment词法规则

其解释的很清楚了,就相当于:

私有变量,不希望外部访问的变量。

用于其他(函数或变量)去调用的。

例子:

grammar TestFragment;

options {

  language=CSharp;

  output=AST;

}

a : INT;

INT : DIGIT+;

fragment DIGIT : '0' .. '9';

2.然后才注意到,fragment,本身就是,片段的意思,即被其他,相对完整的整体,去调用的。

3.又参考了:

What does “fragment” means in ANTLR?

其把fragment,解释为,类似于inline函数,觉得更加贴切。

其不能单独作为一个表示,仅仅是被用于别人调用。

对应举例为:

NUMBER: DIGITS | OCTAL_DIGITS | HEX_DIGITS;
fragment DIGITS: '1'..'9' '0'..'9'*;
fragment OCTAL_DIGITS: '0' '0'..'7'+;
fragment HEX_DIGITS: '0x' ('0'..'9' | 'a'..'f' | 'A'..'F')+;

 

4.官网:

Lexing XML with ANTLR 3

中的解释为:

是叫做sub rule,其无法再被细分;

 

【总结】

antlr中的fragment的含义:

  • fragment的字面意思,就是片段,就是用于别的,完整的整体,所调用的;
  • 其本身不能单独作为一个token(标示),(只能被别人调用,使用)
  • 其含义有点类似于:
    • inline函数,达到直接替换的效果
    • 结构体或类的私有变量(不被外界所访问,仅供自己(文件内部)所使用)

    【后记 2013-03-19】

    1.后来,在折腾:

    【未解决】antlr解析字符串STRING出错:no viable alternative at input,对应的错误是NoViableAltException(0@[null])

    的过程中,又继续学习了fragment。

    但是还是没有完全搞懂。

    2.对于fragment的解释,后来找到了官网的解释:

    Five minute introduction to ANTLR 3

    中的:

    Special constructs (reference)

    Construct

    Description

    Example

    (...)*

    Kleene closure – matches zero or more occurrences

    LETTER DIGIT* – match a LETTER followed by zero or more occurrences of DIGIT

    (...)+

    Positive Kleene closure – matches one or more occurrences

    ('0'..'9')+ – match one or more occurrences of a numerical digit


    LETTER (LETTER|DIGIT)+ – match a LETTER followed one or more occurrences of either LETTER or DIGIT

    fragment

    fragment in front of a lexer rule instructs ANTLR that the rule is only used as part of another lexer rule (i.e. it only builds a fragment of a recognized token)

    fragment {{ DIGIT : ‘0’..’9′ ;


    NUMBER : (DIGIT)+ (‘.’ (DIGIT)+ )? ;}}

    有空继续。



    发表评论

    电子邮件地址不会被公开。 必填项已用*标注

    无觅相关文章插件,快速提升流量