1

我的语法有问题。

它说决策可以匹配输入,例如"{EQUAL, GREATER..GREATER_EQUAL, LOWER..LOWER_EQUAL, NOT_EQUAL}" using multiple alternatives: 1, 2,尽管所有规则树都是正确的。

有人帮忙吗?!

grammar test;
//parser    :   .* EOF;
program     :T_PROGRAM ID T_LEFTPAR identifier_list T_RIGHTPAR T_SEMICOLON declarations subprogram_declarations compound_statement T_DOT;
identifier_list :(ID) (',' ID)*;
declarations    :() (T_VAR identifier_list COLON type T_SEMICOLON)* ;
type        : standard_type|
        T_ARRAY T_LEFTBRACK NUM T_TO NUM T_RIGHTBRACK T_OF standard_type    ;
standard_type   : INT
        | FLOAT ;
subprogram_declarations :() (subprogram_declaration T_SEMICOLON)* ;
subprogram_declaration  : subprogram_head declarations compound_statement;
subprogram_head :T_FUNCTION ID arguments COLON standard_type |
         T_PROCEDURE ID arguments ;
arguments   :T_LEFTPAR parameter_list T_RIGHTPAR    |   ;
parameter_list :(identifier_list COLON type) (T_SEMICOLON identifier_list COLON type)*;
compound_statement : T_BEGIN optional_statements T_END;
optional_statements :statement_list |    ;
statement_list :(statement) (T_SEMICOLON statement)*;

statement :
variable ASSIGN expression
| procedure_statement
| compound_statement
| T_IF expression T_THEN statement T_ELSE statement
| T_WHILE expression T_DO statement
;
procedure_statement :ID
        | ID T_LEFTPAR expression_list T_RIGHTPAR;

expression_list : (expression) (',' expression)*;
variable : ID T_LEFTBRACK expression T_RIGHTBRACK |  ;

expression :( () |simple_expression) (( LOWER | LOWER_EQUAL | GREATER | GREATER_EQUAL | EQUAL | NOT_EQUAL ) simple_expression)* ;

simple_expression :
( () | sign ) term (( PLUS | MINUS | T_OR ) term)*;

term :
(factor) (( CROSS | DIVIDE | MOD | T_AND ) factor)*;

factor :
variable
|ID T_LEFTPAR expression_list T_RIGHTPAR
| NUM
| T_LEFTPAR expression T_RIGHTPAR
| T_NOT factor;

sign    :   
'+'
    |   '-';

/********/


T_PROGRAM :  'program';
T_FUNCTION :    'function';
T_PROCEDURE :   'procedure';    
T_READ  :    'read';
T_WRITE :    'write';
T_OF    :    'of';
T_ARRAY :    'array';
T_VAR   :    'var';
T_FLOAT :    'float';
T_INT   :    'int';
T_CHAR  :    'char';
T_STRING  :  'string';
T_BEGIN   :      'begin';
T_END   :    'end';
T_IF    :    'if';
T_THEN  :    'then';
T_ELSE  :    'else';
T_WHILE :    'while';
T_DO    :    'do';
T_NOT   :   'not';


NUM :   INT
    |   FLOAT;
STRING
    :  '"' ( ESC_SEQ | ~('\\'|'"') )* '"'
    ;

CHAR:  '\'' ( ESC_SEQ | ~('\''|'\\') ) '\''
    ;
ID  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
    ;



COMMENT
    :   '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
    |   '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
    ;



LOWER                : '<';
LOWER_EQUAL          : '<=';
GREATER                : '>';
GREATER_EQUAL          : '>=';
EQUAL                : '=';
NOT_EQUAL            : '<>';

ASSIGN  :   
    ':=';
COLON : 
    ':';

PLUS    :   '+';
MINUS   :   '-';
T_OR    :   'OR';


CROSS   :   '*';
DIVIDE  :   '/';
MOD     :   'MOD';
T_AND   :   'AND';


T_LEFTPAR
     :  '(';
T_RIGHTPAR
     : ')';
T_LEFTBRACK
      : '[';
T_RIGHTBRACK
     :  ']';
T_TO 
    : '..';
T_DOT   : '.';
T_SEMICOLON
    :   ';';
T_COMMA
     : ',';
T_BADNUM
     : (NUM)(CHAR)*;
T_BADSTRING
    :   '"' ( ESC_SEQ | ~('\\'|'"') )*WS; 




WS  :   ( ' '
        | '\t'
        | '\r'
        | '\n'
        ) {$channel=HIDDEN;}
    ;

fragment
EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;

fragment
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;

fragment
ESC_SEQ
    :   '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
    |   UNICODE_ESC
    |   OCTAL_ESC
    ;

fragment
OCTAL_ESC
    :   '\\' ('0'..'3') ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7')
    ;

fragment
UNICODE_ESC
    :   '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
    ;

fragment
INT :   '0'..'9'+
    ;
fragment
FLOAT
    :   ('0'..'9')+ '.' ('0'..'9')* EXPONENT?
    |   '.' ('0'..'9')+ EXPONENT?
    |   ('0'..'9')+ EXPONENT
    ;
4

1 回答 1

0

问题 1

歧义(某些输入可以以不止一种方式匹配的错误/警告)主要源于您variableexpression规则都可以匹配空输入的事实:

variable
 : ID T_LEFTBRACK expression T_RIGHTBRACK
 | /* nothing */ 
 ;

expression
 : (
       (/* nothing */) 
     | simple_expression
   ) 
   (
     (LOWER | LOWER_EQUAL | GREATER | GREATER_EQUAL | EQUAL | NOT_EQUAL) simple_expression
   )* /* because of the `*`, this can also match nothing */
 ;

(我添加了/* ... */评论并重新格式化了规则以使其更具可读性)

修复 1

您可能希望这样做:

variable
 : ID T_LEFTBRACK expression T_RIGHTBRACK
 ;

expression
 : simple_expression ((LOWER | LOWER_EQUAL | GREATER | GREATER_EQUAL | EQUAL | NOT_EQUAL) simple_expression)*
 ;

问题 2

另一个问题(一旦您解决了歧义就会出现的问题是您定义了 tokens MODT_AND并且T_OR 您的ID规则之后:

ID  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
    ;

...

MOD     :   'MOD';
T_AND   :   'AND';
T_OR    :   'OR';

这将导致MOD,T_AND并且T_OR永远不会被创建,因为ID也匹配这些字符。

修复 2

放置MOD,T_ANDT_OR 您的ID规则之前:

MOD     :   'MOD';
T_AND   :   'AND';
T_OR    :   'OR';

...

ID  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
    ;
于 2013-07-16T19:22:52.427 回答