antlr4文字字符串处理

时间:2016-07-04 15:35:26

标签: antlr4 string-literals

我有以下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 个答案:

答案 0 :(得分:1)

请注意,字符串从第一个引号到最后一个可能引用匹配。

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

STRING: '"' CHAR* '"';

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

让它变得非贪婪。