我的 antlr 文件是
class CalculatorParser extends Parser;expr returns [float value=0]
{float x;}
    :   value=mexpr
        ( PLUS x=mexpr  {value += x;}
        | MINUS x=mexpr {value -= x;} 
        )*
    ;mexpr returns [float value=0]
{float x;}
    :   value=atom ( STAR x=atom {value *= x;} | DIV x=atom {value=value * 100 / x * 0.01f;}  )*
    ;
atom returns [float value=0]
    :   i:INT {value=Integer.parseInt(i.getText());}
| LPAREN value=expr RPAREN 
;
class CalculatorLexer extends Lexer;
options {
    k=2; // needed for newline junk
    charVocabulary='\u0000'..'\u007F'; // allow ascii
}LPAREN: '(' ;
RPAREN: ')' ;
PLUS  : '+' ;
MINUS : '-' ;
STAR  : '*' ;
DIV   : '/' ;
INT   : ('0'..'9')+ ;
WS    : ( ' '
        | '\r' '\n'
        | '\n'
        | '\t'
        )
        {$setType(Token.SKIP);}
      ;   
==============================
问题是如果输入负数 就会报错~~
在网上看到个C#的antlr文件
=================
/******************************\
         Calc Parser            
\******************************/
class CalcParser extends Parser;
options
{
 exportVocab = Calc;
 buildAST = true;
}
expr
 : sumExpr EOF
 ;
sumExpr
 : mulExpr ( ( SUM^ | NEG^ ) mulExpr )*
 ;
mulExpr
 : powExpr ( ( MUL^ | DIV^ ) powExpr )*
 ;
powExpr
 : negExpr ( POW^ negExpr )*
 ;
negExpr
 : ( NEG^ )* a:atom!
  {
   if (#negExpr != null) {
    AST lastNegNode = #negExpr;
    while (lastNegNode.getNumberOfChildren() > 0) {
     lastNegNode = lastNegNode.getFirstChild();
    }
    lastNegNode.setFirstChild(#a);
   } else {
    ## = #a;
   }
  }
 ;
atom 
 : NUMBER
 | LCURLY sumExpr RCURLY
 ;
/***************************\
        Calc Lexer 
\***************************/
class CalcLexer extends Lexer;
options
{
 caseSensitive = false;
exportVocab = Calc;
}
WS
 : ( ' '
  | '\t'
  | '\n'
  | '\r' )+ { $setType(Token.SKIP); }
 ;
NUMBER
 : ( ( '0'..'9' )+ '.' ( '0'..'9' )+ ) => ( '0'..'9' )+ '.' ( '0'..'9' )+
 | '0'..'9'
 ;
SUM : '+' ;
NEG : '-' ;
MUL : '*' ;
DIV : '/' ;
POW : '^' ;
LCURLY : '(' ;
RCURLY : ')' ;请问这个文件能能编译出判断负数的四则运算吗?
#号描述是什么作用?
不理解:
negExpr
 : ( NEG^ )* a:atom!
  {
   if (#negExpr != null) {
    AST lastNegNode = #negExpr;
    while (lastNegNode.getNumberOfChildren() > 0) {
     lastNegNode = lastNegNode.getFirstChild();
    }
    lastNegNode.setFirstChild(#a);
   } else {
    ## = #a;
   }
  }
 ;
能帮我分析一下吗?