2017-09-16 103 views
0

我有3种类型的数字,数字,小数和百分比。Antlr没有识别号码

Percentage : (Sign)? Digit+ (Dot Digit+)? '%' ;
Number : Sign? Digit+;
Decimal : Sign? Digit+ Dot Digit*;

百分比和小数做工精细,但当我给你一个数字,除非我把一个符号(+或 - )在号码前面,它不承认它是一个号码。
number foo = +5 // does recognize
number foo = 5; // does not recognize

它识别它在评价表达。
if (foo == 5) // does recognize

这是我的语言(我拿出功能,只留下语言识别)。

grammar Fetal; 
transaction : begin statements end; 

begin  : 'begin' ; 

end   : 'end' ; 


statements : (statement)+ 
      ; 


statement 
      : declaration ';' 
      | command ';' 
      | assignment ';' 
      | evaluation 
      | ';' 
      ; 

declaration : type var; 

var returns : identifier; 


type returns 
      : DecimalType 
      | NumberType 
      | StringType 
      | BooleanType 
      | DateType 
      | ObjectType 
      | DaoType 
      ; 

assignment 
      : lharg Equals rharg 
      | lharg unaryOP rharg 
      ; 


assignmentOp : Equals 
       ; 

unaryOP   : PlusEquals 
       | MinusEquals 
       | MultiplyEquals 
       | DivideEquals 
       | ModuloEquals 
       | ExponentEquals 
       ; 

expressionOp : arithExpressOp 
       | bitwiseExpressOp 
       ; 

arithExpressOp : Multiply 
       | Divide 
       | Plus 
       | Minus 
       | Modulo 
       | Exponent 
       ; 

bitwiseExpressOp 
       : And 
       | Or 
       | Not 
       ; 

comparisonOp : IsEqualTo 
       | IsLessThan 
       | IsLessThanOrEqualTo 
       | IsGreaterThan 
       | IsGreaterThanOrEqualTo 
       | IsNotEqualTo 
       ; 

logicExpressOp : AndExpression 
       | OrExpression 
       | ExclusiveOrExpression 
       ; 

rharg returns  
      : rharg expressionOp rharg 
      | '(' rharg expressionOp rharg ')' 
      | var 
      | literal 
      | assignmentCommands 
      ; 

lharg returns : var; 

identifier : Identifier; 

evaluation : IfStatement '(' evalExpression ')' block (Else block)?; 


block : OpenBracket statements CloseBracket; 


evalExpression 
       : evalExpression logicExpressOp evalExpression 
       | '(' evalExpression logicExpressOp evalExpression ')' 
       | eval 
       | '(' eval ')' 
       ; 


eval : rharg comparisonOp rharg ; 


assignmentCommands 
      : GetBalance '(' stringArg ')' 
      | GetVariableType '(' var ')' 
      | GetDescription 
      | Today 
      | GetDays '(' startPeriod=dateArg ',' endPeriod=dateArg ')' 
      | DayOfTheWeek '(' dateArg ')' 
      | GetCalendarDay '(' dateArg ')' 
      | GetMonth '(' dateArg ')' 
      | GetYear '(' dateArg ')' 
      | Import '(' stringArg ')' /* Import(path) */ 
      | Lookup '(' sql=stringArg ',' argumentList ')' /* Lookup(table, SQL) */ 
      | List '(' sql=stringArg ',' argumentList ')' /* List(table, SQL) */ 
      | invocation 
      ; 



command  : Print '(' rharg ')' 
      | Credit '(' amtArg ',' stringArg ')' 
      | Debit '(' amtArg ',' stringArg ')' 
      | Ledger '(' debitOrCredit ',' amtArg ',' acc=stringArg ',' desc=stringArg ')' 
      | Alias '(' account=stringArg ',' name=stringArg ')' 
      | MapFile ':' stringArg 
      | invocation 
      | Update '(' sql=stringArg ',' argumentList ')' 
      ; 

invocation 
      : o=objectLiteral '.' m=identifier '('argumentList? ')' 
      | o=objectLiteral '.' m=identifier '()' 
      ; 

argumentList 
      : rharg (',' rharg)* 
      ; 

amtArg : rharg ; 

stringArg : rharg ; 

numberArg : rharg ; 

dateArg : rharg ; 

debitOrCredit : charLiteral ; 

literal 
      : numericLiteral 
      | doubleLiteral 
      | booleanLiteral 
      | percentLiteral 
      | stringLiteral 
      | dateLiteral 
      ; 


fileName : '<' fn=Identifier ('.' ft=Identifier)? '>' ; 

charLiteral  : ('D' | 'C'); 

numericLiteral : Number ; 

doubleLiteral : Decimal ; 

percentLiteral : Percentage ; 

booleanLiteral : Boolean ; 

stringLiteral : String ; 

dateLiteral  : Date ; 

objectLiteral : Identifier ; 

daoLiteral  : Identifier ; 

//Below are Token definitions 

// Data Types 
DecimalType  : 'decimal' ; 
NumberType  : 'number' ; 
StringType  : 'string' ; 
BooleanType  : 'boolean' ; 
DateType  : 'date' ; 
ObjectType  : 'object' ; 
DaoType   : 'dao' ; 
/****************************************************************** 
* Assignmnt operator 
******************************************************************/ 
Equals   : '=' ; 

/***************************************************************** 
    * Unary operators 
    *****************************************************************/ 
PlusEquals  : '+=' ; 
MinusEquals  : '-=' ; 
MultiplyEquals : '*=' ; 
DivideEquals : '/=' ; 
ModuloEquals : '%=' ; 
ExponentEquals : '^=' ; 

/***************************************************************** 
* Binary operators 
*****************************************************************/ 
Plus   : '+' ; 
Minus   : '-' ; 
Multiply  : '*' ; 
Divide   : '/' ; 
Modulo   : '%' ; 
Exponent  : '^' ; 

/*************************************************************** 
    * Bitwise operators 
    ***************************************************************/ 
    And   : '&' ; 
    Or   : '|' ; 
    Not   : '!' ; 

/************************************************************* 
    * Compariso operators 
    *************************************************************/ 
    IsEqualTo     : '==' ; 
    IsLessThan    : '<' ; 
    IsLessThanOrEqualTo  : '<=' ; 
    IsGreaterThan    : '>' ; 
    IsGreaterThanOrEqualTo : '>=' ; 
    IsNotEqualTo    : '!=' ; 

/************************************************************* 
    * Expression operators 
    *************************************************************/ 
    AndExpression   : '&&' ; 
    OrExpression   : '||' ; 
    ExclusiveOrExpression : '^^' ; 

// Reserve words (Assignment Commands) 
GetBalance  : 'getBalance'; 
GetVariableType : 'getVariableType' ; 
GetDescription : 'getDescription' ; 
Today   : 'today'; 
GetDays   : 'getDays' ; 
DayOfTheWeek : 'dayOfTheWeek' ; 
GetCalendarDay : 'getCalendarDay' ; 
GetMonth  : 'getMonth' ; 
GetYear   : 'getYear' ; 
Import   : 'import' ; 
Lookup   : 'lookup' ; 
List   : 'list' ; 


// Reserve words (Commands) 
Credit   : 'credit'; 
Debit   : 'debit'; 
Ledger   : 'ledger'; 
Alias   : 'alias' ; 
MapFile   : 'mapFile' ; 
Update   : 'update' ; 
Print   : 'print'; 

IfStatement : 'if'; 
Else  : 'else'; 
OpenBracket : '{'; 
CloseBracket : '}'; 

Percentage : (Sign)? Digit+ (Dot Digit+)? '%' ; 

Boolean  : 'true' | 'false'; 

Number  : Sign? Digit+; 


Decimal  : Sign? Digit+ Dot Digit*; 

Date  : Year '-' Month '-' Day; 

Identifier 
    : IdentifierNondigit 
     ( IdentifierNondigit 
     | Digit 
     )* 
    ; 
String: '"' (ESC | ~[\\"])* '"'; 

/************************************************************ 
* Fragment Definitions 
************************************************************/ 

fragment 
ESC : '\\' [abtnfrv"'\\] 
    ; 

fragment 
IdentifierNondigit 
    : Nondigit 
    //| // other implementation-defined characters... 
    ; 
fragment 
Nondigit 
    : [a-zA-Z_] 
    ; 

fragment 
Digit 
    : [0-9] 
    ; 
fragment 
Sign : Plus | Minus; 

fragment 
Digits 
    : [-+]?[0-9]+ 
    ; 

fragment 
Year 
    : Digit Digit Digit Digit; 

fragment 
Month 
    : Digit Digit; 

fragment 
Day 
    : Digit Digit; 


fragment Dot : '.'; 


fragment 
SCharSequence 
    : SChar+ 
    ; 

fragment 
SChar 
    : ~["\\\r\n] 
    | SimpleEscapeSequence 
    | '\\\n' // Added line 
    | '\\\r\n' // Added line 
    ; 


fragment  
CChar 
    : ~['\\\r\n] 
    | SimpleEscapeSequence 
    ; 

fragment 
SimpleEscapeSequence 
    : '\\' ['"?abfnrtv\\] 
    ; 

ExtendedAscii 
    : [\x80-\xfe]+ 
    -> skip 
    ; 
Whitespace 
    : [ \t]+ 
     -> skip 
    ; 

Newline 
    : ( '\r' '\n'? 
     | '\n' 
     ) 
     -> skip 
    ; 

BlockComment 
    : '/*' .*? '*/' 
     -> skip 
    ; 



LineComment 
    : '//' ~[\r\n]* 
     -> skip 
    ; 
+2

当我用4.6编译你的语法时,我有5个错误。第一个是没有分号的'end'规则。对于标识识别的具体问题提出问题太长(400行)。例如,'command'规则与这个问题无关,我不打算去理解整个语法。你应该将它减少到解析'number foo = [+] 5'和'if(foo == 5)'所需的严格最小规则,否则没有人会花时间回答你的问题。 – BernardK

+0

我可以把它砍下来。 –

+0

顺便说一句,'开始'和'结束'不应该有分号。他们不是陈述,他们只是定义交易的开始和结束。 –

回答

0

我有一种预感,这使用的一个片段是不正确的:

fragment Sign : Plus | Minus; 

我找不到在参考书什么,但我认为它需要改变,以这样的事:

fragment Sign : [+-]; 
0

我发现了这个问题。我使用的版本是4.5.2-1,因为每次尝试升级到4.7都会导致更多的错误,并且我不想在解决另一个错误时导致更多的错误。我终于打破了,并将库升级到4.7,修复了错误,数字识别问题消失了。这一直是图书馆的一个错误。