2016-07-04 403 views
0

我有以下antlr4语法:antlr4文字字符串处理

grammar squirrel; 

program: globalstatement+; 

globalstatement: globalvardef | classdef | functiondef; 

globalvardef: IDENT '=' constantexpr ';'; 

classdef: CLASS IDENT '{' classstatement+ '}'; 

functiondef: FUNCTION IDENT '(' parameterlist ')' functionbody; 

constructordef: CONSTRUCTOR '(' parameterlist ')' functionbody; 

parameterlist: IDENT (',' IDENT)* | ; 

functionbody: '{' statement* '}'; 

classstatement: globalvardef | functiondef | constructordef; 

statement: expression ';'; 


expression: 
    IDENT # ident | 
    IDENT '=' expression # assignment | 
    IDENT ('.' IDENT)+ # lookupchain | 
    constantexpr # constant | 
    IDENT '(' expressionlist ')' # functioncall | 
    expression '+' expression # addition; 

constantexpr: INTEGER | STRING; 

expressionlist: expression (',' expression)* | ; 

CONSTRUCTOR: 'constructor'; 
CLASS: 'class'; 
FUNCTION: 'function'; 
COMMENT: '//'.*[\n]; 
STRING: '"' CHAR* '"'; 
CHAR: [ a-zA-Z0-9]; 
INTEGER: [0-9]+; 
IDENT: [a-zA-Z]+; 
WS: [ \t\r\n]+ -> skip; 

现在,如果我分析这个文件:

z = "global variable"; 

class Base 
{ 
    z = 10; 
} 

一切都很好:

@0,0:0='z',<16>,1:0 
@1,2:2='=',<1>,1:2 
@2,4:20='"global variable"',<14>,1:4 
@3,21:21=';',<2>,1:21 
@4,26:30='class',<11>,3:0 
@5,32:35='Base',<16>,3:6 
@6,38:38='{',<3>,4:0 
@7,42:42='z',<16>,5:1 
@8,44:44='=',<1>,5:3 
@9,46:47='10',<15>,5:5 
@10,48:48=';',<2>,5:7 
@11,51:51='}',<4>,6:0 
@12,56:55='<EOF>',<-1>,8:0 

但有了这个文件:

z = "global variable"; 

class Base 
{ 
    z = "10"; 
} 

我得到这个:

@0,0:0='z',<16>,1:0 
@1,2:2='=',<1>,1:2 
@2,4:49='"global variable";\r\n\r\nclass Base\r\n{\r\n\tz = "10"',<14>,1:4 
@3,50:50=';',<2>,5:9 
@4,53:53='}',<4>,6:0 
@5,58:57='<EOF>',<-1>,8:0 

所以它看起来像在一个文件中的第一个“和最后一个”被匹配到一个字符串字面量之间的一切。

我该如何预防?

回答

1

注意字符串从第一个报价到最后一个可能的报价是匹配的。

默认情况下,ANTLR中的Kleene运算符(*)是贪婪的。因此,改变

STRING: '"' CHAR* '"'; 

STRING: '"' CHAR*? '"'; 

,使其非贪婪。