ANTLR简单语法和标识符

时间:2011-12-23 14:31:54

标签: antlr grammar lexer context-free-grammar parser-generator

我为ANTLR写了这个简单的语法

grammar ALang;

@members {

public static void main(String[] args) throws Exception {   
    ALangLexer lex = new ALangLexer(new ANTLRFileStream("antlr/ALang.al"));
    CommonTokenStream tokens = new CommonTokenStream(lex);
    ALangParser parser = new ALangParser(tokens);
    parser.prog();
} 

}

prog : 
    ID | PRINT
    ;

PRINT : 'print';
ID : ( 'a'..'z' | 'A'..'Z' )+;
WS : (' ' | '\t' | '\n' | '\r')+ { skip(); };

用作输入:

print

找到的唯一令牌是ID类型的令牌。仅仅是在ID定义之前放置PRINT标记定义吗?

1 个答案:

答案 0 :(得分:1)

  

ALang.g:21:1:永远不能匹配以下令牌定义,因为先前的令牌匹配相同的输入:PRINT

是的,这就够了。如果您在 PRINT之后定义ID ,ANTLR将产生错误:

ALang.g:21:1: The following token definitions can never be matched because prior tokens match the same input: PRINT 
  

我很抱歉,我不想用这个作品:PRINT:'print';但没有尾随空格的制作:PRINT:'print';问题是'print'是从ID而不是PRINT

派生的

不,情况并非如此。

以下内容:

grammar ALang;

@members {
  public static void main(String[] args) throws Exception {  
    ALangLexer lex = new ALangLexer(new ANTLRStringStream("sprint print prints foo"));
    CommonTokenStream tokens = new CommonTokenStream(lex);
    ALangParser parser = new ALangParser(tokens);
    parser.prog();
  } 
}

prog
 : ( ID    {System.out.printf("ID    :: '\%s'\n", $ID.text);}
   | PRINT {System.out.printf("PRINT :: '\%s'\n", $PRINT.text);}
   )*
   EOF
 ;

PRINT : 'print';
ID    : ('a'..'z' | 'A'..'Z')+;
WS    : (' ' | '\t' | '\n' | '\r')+ {skip();};

将打印:

ID    :: 'sprint'
PRINT :: 'print'
ID    :: 'prints'
ID    :: 'foo'

如您所见,PRINT规则 匹配"print"