我的ANTLR语法文件有什么问题?

时间:2014-07-17 19:18:59

标签: antlr

我按照Scott Stanchfield教程定义了以下语法。

grammar SampleScript;

program
    :
        declaration+
    ;

declaration
    :    macrodeclaration
    ;

macrodeclaration
    :
        MACRO STRING (LEFTPAREN parameters RIGHTPAREN)?
        statement*
        ENDMACRO
    ;

statement
    :   assignmentStatement
    |   ifStatement 
    |   iterationStatement
    |   jumpStatement
    |   procedureCallStatement
    |   dimStatement
    |   labeledStatement
    ;

actualParameters
    :   expression (',' expression?)*
    ;

parameters
    :   ID (',' ID)*
    ;   

assignmentStatement
    :   ID ASSIGN expression
    |   ID MATRIXASSIGN expression        
    ;
ifStatement
    :   IF expression THEN (statement|compoundStatement)
            (ELSE expression (statement|compoundStatement))?        
    ;

iterationStatement
    :   WHILE expression compoundStatement
    |   FOR ID '=' expression TO expression (STEP expression)? compoundStatement
    ;

jumpStatement
    : BREAK
    | CONTINUE
    | GOTO ID
    | RETURN LEFTPAREN expression RIGHTPAREN
    ;

procedureCallStatement //todo: expression statement
    :   ID LEFTPAREN actualParameters? RIGHTPAREN
    ;

dimStatement
    :   DIM ID LEFTBRACKET expression(',' expression)* RIGHTBRACKET (',' ID LEFTBRACKET expression(',' expression)* RIGHTBRACKET)*
    ;

labeledStatement
    :   ID ':' statement
    ;

compoundStatement
    :   DO statement* END
    ;

term
    :   NUMBER
    |   STRING
    |   ID
    |   LEFTPAREN expression RIGHTPAREN    //( )
    |   ID LEFTPAREN actualParameters RIGHTPAREN  //Procedure Call
    |   ID (LEFTBRACKET expression RIGHTBRACKET)+ //Array Arr[3]
    |   ID ('.' expression)+                      //Array Arr.Length
    |   LEFTBRACE (expression)? (',' expression)* RIGHTBRACE  //{"OK","False"}
    ;

negation
    :   'not'* term
    ;

unary
    :   ('-')* negation
    ;

mult
    :   unary (('*' | '/') unary)*
    ;

add
    :   mult (('+' | '-') mult)*
    ;

relation
    :   add (('=' | '/=' | '<' | '<=' | '>=' | '>') add)*
    ;

expression
    :   relation (('and' | 'or') relation)*
    ;

//Keywords
DIM: D I M;
RETURN: R E T U R N;
FOR: F O R;
STEP: S T E P;
TO: T O;
WHILE: W H I L E;
DO: D O;
END: E N D;
GOTO: G O T O;
BREAK: B R E A K;
CONTINUE: C O N T I N U E;
IF: I F;
THEN: T H E N;
ELSE: E L S E;
MACRO :M A C R O;   
ENDMACRO :E N D M A C R O;    
ID : ('_'|LETTER) ('_'|LETTER|DIGIT)*;

ASSIGN: '=';
MATRIXASSIGN: ':=';
LEFTPAREN : '(';
RIGHTPAREN : ')';
LEFTBRACKET : '[';
RIGHTBRACKET : ']';
LEFTBRACE : '{';
RIGHTBRACE : '}';

//STRING : '"' .*? '"' ; // match anything in "..."
STRING
    :   '"' (STRING_ESCAPE_SEQ|~('\n'|'\r'))*? '"' 
    |   '\'' (STRING_ESCAPE_SEQ|~('\n'|'\r'))*? '\'' 
;

/// stringescapeseq ::=  "\" <any source character>
fragment STRING_ESCAPE_SEQ  //'\\"'
 : '\\' .
 ; 

UNSIGNED_INT :      DIGIT+;  //('0' | '1'..'9' '0'..'9'*); 
UNSIGNED_FLOAT:     DIGIT+ '.' DIGIT* Exponent?
              |     '.' DIGIT+ Exponent?
              |     DIGIT+ Exponent
              ;
NUMBER
    :   UNSIGNED_INT 
    |   UNSIGNED_FLOAT
    ;

fragment DIGIT : [0-9] ; // not a token by itself        
fragment Exponent : ('e'|'E') ('+'|'-')? (DIGIT)+ ;

LINE_COMMENT : '//' .*? '\r'? '\n' -> skip ; // Match "//" stuff '\n'
COMMENT : '/*' .*? '*/' -> skip ; // Match "/*" stuff "*/"  

fragment A:('a'|'A');
fragment B:('b'|'B');
fragment C:('c'|'C');
fragment D:('d'|'D');
fragment E:('e'|'E');
fragment F:('f'|'F');
fragment G:('g'|'G');
fragment H:('h'|'H');
fragment I:('i'|'I');
fragment J:('j'|'J');
fragment K:('k'|'K');
fragment L:('l'|'L');
fragment M:('m'|'M');
fragment N:('n'|'N');
fragment O:('o'|'O');
fragment P:('p'|'P');
fragment Q:('q'|'Q');
fragment R:('r'|'R');
fragment S:('s'|'S');
fragment T:('t'|'T');
fragment U:('u'|'U');
fragment V:('v'|'V');
fragment W:('w'|'W');
fragment X:('x'|'X');
fragment Y:('y'|'Y');
fragment Z:('z'|'Z');

fragment LETTER : [A-Za-z];
WS : [ \t\n\r]+ -> skip ; // skip spaces, tabs, newlines

我正在尝试解析以下代码

Macro 'test' (x)

a=1
b=2
c={}
d = x(3,4)
matrixinfo_skim = GetMatrixInfo(m_skim)

showmessage (i2s(a))
showarray(c)
endmacro 

并得到下面的错误,我花了2天多的时间在它上面并且无法弄清楚为什么它无法解析a = 1及更高版本的赋值语句?有人请帮帮我..

[@0,0:4='Macro',<30>,1:0]
[@1,6:11=''test'',<41>,1:6]
[@2,13:13='(',<35>,1:13]
[@3,14:14='x',<32>,1:14]
[@4,15:15=')',<36>,1:15]
[@5,20:20='a',<32>,3:0]
[@6,21:21='=',<33>,3:1]
[@7,22:22='1',<42>,3:2]
[@8,25:25='b',<32>,4:0]
[@9,26:26='=',<33>,4:1]
[@10,27:27='2',<42>,4:2]
[@11,30:30='c',<32>,5:0]
[@12,31:31='=',<33>,5:1]
[@13,32:32='{',<39>,5:2]
[@14,33:33='}',<40>,5:3]
[@15,36:36='d',<32>,6:0]
[@16,38:38='=',<33>,6:2]
[@17,40:40='x',<32>,6:4]
[@18,41:41='(',<35>,6:5]
[@19,42:42='3',<42>,6:6]
[@20,43:43=',',<2>,6:7]
[@21,44:44='4',<42>,6:8]
[@22,45:45=')',<36>,6:9]
[@23,48:62='matrixinfo_skim',<32>,7:0]
[@24,64:64='=',<33>,7:16]
[@25,66:78='GetMatrixInfo',<32>,7:18]
[@26,79:79='(',<35>,7:31]
[@27,80:85='m_skim',<32>,7:32]
[@28,86:86=')',<36>,7:38]
[@29,91:101='showmessage',<32>,9:0]
[@30,103:103='(',<35>,9:12]
[@31,104:106='i2s',<32>,9:13]
[@32,107:107='(',<35>,9:16]
[@33,108:108='a',<32>,9:17]
[@34,109:109=')',<36>,9:18]
[@35,110:110=')',<36>,9:19]
[@36,113:121='showarray',<32>,10:0]
[@37,122:122='(',<35>,10:9]
[@38,123:123='c',<32>,10:10]
[@39,124:124=')',<36>,10:11]
[@40,127:134='endmacro',<31>,11:0]
[@41,140:139='<EOF>',<-1>,13:0]
line 3:2 extraneous input '1' expecting {'-', 'not', ID, '(', '{', STRING, NUMBER}
line 4:2 extraneous input '2' expecting {'-', 'not', ID, '(', '{', STRING, NUMBER}
line 6:6 mismatched input '3' expecting {'-', 'not', ID, '(', '{', STRING, NUMBER}
line 6:8 extraneous input '4' expecting {',', ')'}
(program (declaration (macrodeclaration Macro 'test' ( (parameters x) ) (statement (assignmentStatement a = (expression (relation (add (mult (unary 1 (negation (term b))))) = (add (mult (unary 2 (negation (term c))))) = (add (mult (unary (negation (term { }))))))))) (statement (assignmentStatement d = (expression (relation (add (mult (unary (negation (term x ( (actualParameters (expression (relation (add (mult (unary 3))))) , 4) )))))))))) (statement (assignmentStatement matrixinfo_skim = (expression (relation (add (mult (unary (negation (term GetMatrixInfo ( (actualParameters (expression (relation (add (mult (unary (negation (term m_skim)))))))) )))))))))) (statement (procedureCallStatement showmessage ( (actualParameters (expression (relation (add (mult (unary (negation (term i2s ( (actualParameters (expression (relation (add (mult (unary (negation (term a)))))))) ))))))))) ))) (statement (procedureCallStatement showarray ( (actualParameters (expression (relation (add (mult (unary (negation (term c)))))))) ))) endmacro)))

1 个答案:

答案 0 :(得分:2)

正如错误消息所示,expression规则中assignmentStatement匹配的数字出现问题,最终(或应该)匹配为NUMBERterm规则中。

查看负责创建NUMBER令牌的词法规则:

UNSIGNED_INT :      DIGIT+;  
UNSIGNED_FLOAT:     DIGIT+ '.' DIGIT* Exponent?
              |     '.' DIGIT+ Exponent?
              |     DIGIT+ Exponent
              ;
NUMBER
    :   UNSIGNED_INT
    |   UNSIGNED_FLOAT
    ;

似乎永远不会创建NUMBER令牌,因为NUMBERUNSIGNED_INTUNSIGNED_FLOAT匹配。但由于这些2个令牌在之前定义 NUMBER,因此词法分析器会创建UNSIGNED_INTUNSIGNED_FLOAT令牌而不是NUMBER令牌。

您需要将UNSIGNED_INTUNSIGNED_FLOAT更改为fragment规则:

fragment UNSIGNED_INT :      DIGIT+;
fragment UNSIGNED_FLOAT:     DIGIT+ '.' DIGIT* Exponent?
                       |     '.' DIGIT+ Exponent?
                       |     DIGIT+ Exponent
                       ;
NUMBER
    :   UNSIGNED_INT
    |   UNSIGNED_FLOAT
    ;

请务必了解fragment的内容:What does "fragment" mean in ANTLR?