字符串中的Antlr 4空格已被删除

时间:2013-11-12 19:12:08

标签: antlr

我正在使用Antlr 4为构建语言构建编译器。我在正确消除空白方面遇到了问题。它将消除令牌之间的空白,但它也会删除字符串令牌中的空格,这显然不是我想要的。我尝试使用模式来解决这个问题但没有用。

Lexer.g4

lexer grammar WaccLexer;

SEMICOLON: ';' ;

WS: [ \n\t\r\u000C]+ -> skip;

EOL: '\n' ;
BEGIN: 'begin' ;
END: 'end' ;
SKIP: 'skip' ;
READ: 'read' ;
FREE: 'free' ;
RETURN: 'return' ;
EXIT: 'exit' ;
IS: 'is' ;
PRINT: 'print' ;
PRINTLN: 'println' ;
IF: 'if' ;
THEN: 'then' ;
ELSE: 'else' ;
FI: 'fi' ;
WHILE: 'while' ;
DO: 'do' ;
DONE: 'done' ;
NEWPAIR: 'newpair' ;
CALL: 'call' ;
FST: 'fst' ;
SND: 'snd' ;
INT: 'int' ;
BOOL: 'bool' ;
CHAR: 'char' ;
STRING: 'string' ;
PAIR: 'pair' ;
EXCLAMATION: '!' ;
LEN: 'len' ;
ORD: 'ord' ;
TOINT: 'toInt' ;

DIGIT: '0'..'9' ;
LOWCHAR: 'a'..'z' ;

R: 'r' ;
F: 'f' ;
N: 'n' ;
T: 't' ;
B: 'b' ;
ZERO: '0' ;

MULTI: '*' ;
DIVIDE: '/' ;
MOD: '%' ;
PLUS: '+' ;
MINUS: '-' ;
GT: '>' ;
GTE: '>=' ;
LT: '<' ;
LTE: '<=' ;
DOUBLEEQUAL: '==' ;
EQUAL: '=' ;
NOTEQUAL: '!=' ;
AND: '&&' ;
OR: '||' ;
UNDERSCORE: '_' ;
UPCHAR: 'A'..'Z' ;

OPENSQUARE: '[' ;
CLOSESQUARE: ']' ;
OPENPARENTHESIS: '(' ;
CLOSEPARENTHESIS: ')' ;
TRUE: 'true' ;
FALSE: 'false' ;
SINGLEQUOT: '\'' ;
DOUBLEQUOT: '\"' ;
BACKSLASH: '\\' ;
COMMA: ',' ;
NULL: 'null' ;

OPENSTRING : DOUBLEQUOT -> pushMode(STRINGMODE) ;

COMMENT: '#' ~[\r\n]* '\r'? '\n' -> skip ;


mode STRINGMODE ;

CLOSESTRING : DOUBLEQUOT -> popMode ;

CHARACTER : ~[\"\'\\] | (BACKSLASH ESCAPEDCHAR) ;
STRLIT : (CHARACTER)* ;

ESCAPEDCHAR : ZERO
    | B
    | T
    | N
    | F
    | R
    | DOUBLEQUOT
    | SINGLEQUOT
    | BACKSLASH
    ;

Parser.g4

parser grammar WaccParser;

options {
  tokenVocab=WaccLexer;
}

program : BEGIN (func)* stat END EOF;

func : type ident OPENPARENTHESIS (paramlist)? CLOSEPARENTHESIS IS stat END ;

paramlist : param (COMMA param)* ;

param : type ident ;


stat : SKIP                 
| type ident EQUAL assignrhs        
| assignlhs EQUAL assignrhs
| READ assignlhs    
| FREE expr 
| RETURN expr   
| EXIT expr     
| PRINT expr                
| PRINTLN expr          
| IF expr THEN stat ELSE stat FI
| WHILE expr DO stat DONE
| BEGIN stat END    
| stat SEMICOLON stat       
;

assignlhs : ident               
| expr OPENSQUARE expr CLOSESQUARE  
| pairelem                              
;

assignrhs : expr
| arrayliter                                                
| NEWPAIR OPENPARENTHESIS expr COMMA expr CLOSEPARENTHESIS 
| pairelem      
| CALL ident OPENPARENTHESIS (arglist)? CLOSEPARENTHESIS
;

arglist : expr (COMMA expr)* ;

pairelem : FST expr 
| SND expr  
;

type : basetype     
| type OPENSQUARE CLOSESQUARE   
| pairtype  
;

basetype : INT  
| BOOL  
| CHAR  
| STRING 
;

pairtype : PAIR OPENPARENTHESIS pairelemtype COMMA pairelemtype CLOSEPARENTHESIS ;

pairelemtype : basetype     
| type OPENSQUARE CLOSESQUARE   
| PAIR              
;

expr : intliter     
| boolliter         
| charliter         
| strliter          
| pairliter         
| ident             
| expr OPENSQUARE expr CLOSESQUARE  
| unaryoper expr            
| expr binaryoper expr          
| OPENPARENTHESIS expr CLOSEPARENTHESIS 
;

unaryoper : EXCLAMATION             
| MINUS     
| LEN       
| ORD   
| TOINT         
;

binaryoper : MULTI  
| DIVIDE 
| MOD       
| PLUS          
| MINUS nus
| GT            
| GTE       
| LT        
| LTE       
| DOUBLEEQUAL       
| NOTEQUAL      
| AND   
| OR        
;

ident : (UNDERSCORE | LOWCHAR | UPCHAR) (UNDERSCORE | LOWCHAR | UPCHAR | DIGIT)* ;

intliter : (intsign)? (digit)+ ;

digit : DIGIT ;

intsign : PLUS      
| MINUS         
;

boolliter : TRUE 
| FALSE 
;

charliter : CHARACTER;

strliter : OPENSTRING STRLIT CLOSESTRING;

arrayliter : OPENSQUARE (expr (COMMA expr)*)? CLOSESQUARE ;

还请记住,以#开头的注释需要忽略。提前谢谢。

1 个答案:

答案 0 :(得分:0)

OPENSTRING词法分析器规则永远不会在语法中匹配,因为DOUBLEQUOT规则匹配完全相同的输入序列并在语法中出现在它之前。如果要定义词法分析器规则,但实际上并不希望该词法分析器规则自己创建令牌,则需要使用fragment修饰符定义规则。

fragment DOUBLEQUOT : '"';

此外,您需要更正为语法生成代码时出现的警告。其中至少有一个(定义为EPSILON_TOKEN)表示您在ANTLR 4.0中犯了一个主要错误,但在ANTLR 4.1中被更改为警告,因为有一个可以使用它的边缘情况没有问题。