gpt4 book ai didi

java - ANTLR 中解析输入时出错

转载 作者:行者123 更新时间:2023-12-01 11:53:06 25 4
gpt4 key购买 nike

所以我在 ANTLR 中编写了以下语法:

grammar PARVA;


prog : lexeme* ;


lexeme :TOK_STRLIT
| TOK_INTLIT
| TOK_CHARLIT
| ID
| LINE_COMMENT
| COMMENT
| TOK_ASSERT
| TOK_BOOL
| TOK_BOOLEAN
| TOK_BREAK
| TOK_CHAR
| TOK_CIN
| TOK_CONST
| TOK_COUT
| TOK_DO
| TOK_ELSE
| TOK_ENUM
| TOK_EOF
| TOK_EOLN
| TOK_EXIT
| TOK_FALSE
| TOK_FOR
| TOK_GET
| TOK_IF
| TOK_INLINE
| TOK_INT
| TOK_MOD
| TOK_NEW
| TOK_PRINT
| TOK_PRINTLN
| TOK_RANDOM
| TOK_RANDOMSEED
| TOK_READ
| TOK_RETURN
| TOK_STACKDUMP
| TOK_TRUE
| TOK_VAL
| TOK_VOID
| TOK_WHILE
| TOK_WRITE
| TOK_TOUPPER
| TOK_TOLOWER
| TOK_OP_NOT
| TOK_BITOR
| TOK_OR
| TOK_BITAND
| TOK_AND
| TOK_OP_REL
| TOK_OP_ASSIGN
| TOK_OP_ADD
| TOK_OP_TIMES
| TOK_INC
| TOK_DEC
| TOK_COMMA
| TOK_COLON
| TOK_SEMI
| TOK_LSHIFT
| TOK_RSHIFT
| TOK_LB
| TOK_RB
| TOK_LC
| TOK_RC
| TOK_LP
| TOK_RP
| WS
;
Letter : [a-zA-Z] ;
Digit : [0-9] ;
Hex_Digit : [a-fA-F0-9] ;
UNICODE : 'u' Hex_Digit Hex_Digit Hex_Digit Hex_Digit ;
ESC : '\\"'
| '\\\\'
;

TOK_STRLIT : '"' (ESC|.)*? '"' ;
TOK_INTLIT : [0-9]+ ;
TOK_CHARLIT : '\\'('a' | 'b' | 'f' | 'n' | 'r' | 't' | UNICODE ) | '\'' Letter '\'' | '\'' Digit '\'' ;
ID : Letter (Letter | Digit | '_' )* ;
WS : [ \t\r\n]+ -> skip ;



LINE_COMMENT : '//' .*? '\n' -> skip ;
COMMENT : '/*' .*? '*/' -> skip ;

TOK_ASSERT : 'assert' ;
TOK_BOOL : 'bool' ;
TOK_BOOLEAN : 'boolean' ;
TOK_BREAK : 'break' ;
TOK_CHAR : 'char' ;
TOK_CIN : 'cin' ;
TOK_CONST : 'const' ;
TOK_COUT : 'cout' ;
TOK_DO : 'do' ;
TOK_ELSE : 'else' ;
TOK_ENUM : 'enum' ;
TOK_EOF : 'eof' ;
TOK_EOLN : 'eoln' ;
TOK_EXIT : 'exit' ;
TOK_FALSE : 'false' ;
TOK_FOR : 'for' ;
TOK_GET : 'get' ;
TOK_IF : 'if' ;
TOK_INLINE : 'inline' ;
TOK_INT : 'int' ;
TOK_MOD : 'mod' ;
TOK_NEW : 'new' ;
TOK_PRINT : 'print' ;
TOK_PRINTLN : 'println' ;
TOK_RANDOM : 'random' ;
TOK_RANDOMSEED : 'randomseed' ;
TOK_READ : 'read' ;
TOK_RETURN : 'return' ;
TOK_STACKDUMP : 'stackdump' ;
TOK_TRUE : 'true' ;
TOK_VAL : 'val' ;
TOK_VOID : 'void' ;
TOK_WHILE : 'while' ;
TOK_WRITE : 'write' ;
TOK_TOUPPER : 'toUpperCase' ;
TOK_TOLOWER : 'toLowerCase' ;



TOK_OP_NOT : '!' ;
TOK_BITOR : '|' ;
TOK_OR : '||' ;
TOK_BITAND : '&' ;
TOK_AND : '&&' ;
TOK_OP_REL : '=='
| '!='
| '<'
| '<='
| '>'
| '>='
;
TOK_OP_ASSIGN : '='
| '%='
| '&='
| '|='
| '*='
| '+='
| '-='
| '/='
;
TOK_OP_ADD : '+'
| '-'
;
TOK_OP_TIMES : '*'
| '/'
| '%'
;
TOK_INC : '--' ;
TOK_DEC : '++' ;


TOK_COMMA : ',' ;
TOK_COLON : ':' ;
TOK_SEMI : ';' ;
TOK_LSHIFT : '<<' ;
TOK_RSHIFT : '>>' ;
TOK_LB : '[' ;
TOK_RB : ']' ;
TOK_LC : '{' ;
TOK_RC : '}' ;
TOK_LP : '(' ;
TOK_RP : ')' ;

但是当我提供以下内容作为输入时:

int main(){
int a;
}

我收到以下错误:

extraneous input 'a' expecting {<EOF>, TOK_STRLIT, TOK_INTLIT, TOK_CHARLIT, ID, WS, LINE_COMMENT, COMMENT, 'assert', 'bool', 'boolean', 'break', 'char',  'cin', 'const', 'cout', 'do', 'else', 'enum', 'eof', 'eoln', 'exit', 'false',  'for', 'get', 'if', 'inline', 'int', 'mod', 'new', 'print', 'println', 'random', 'randomseed', 'read', 'return', 'stackdump', 'true', 'val', 'void', 'while', 'write', 'toUpperCase', 'toLowerCase', '!', '|', '||', '&', '&&', TOK_OP_REL, TOK_OP_ASSIGN, TOK_OP_ADD, TOK_OP_TIMES, '--', '++', ',', ':', ';', '<<', '>>', '[', ']', '{', '}', '(', ')'}

这真的很令人沮丧,我已经尝试了几个小时,但找不到我做错了什么,而且我对 ANTLR 很陌生,可能是什么问题?

最佳答案

正如评论中提到的(以及指定的重复问题),问题是 a 匹配 Letter,而您希望它匹配 ID >。原则上,发生这种情况是因为 Letter 的定义在语法中早于 ID 的定义。因此您可以通过重新排列定义来修复它。

您还需要移动 Hex_Digit 的定义。然后您会发现 UNICODE 匹配一些名称以 u 开头的标识符。

但我认为您永远想要一个 token 来匹配LetterDigitHex_Digit UNICODEESC。这些仅旨在作为出现在其他词汇规则中的命名片段,而不是其本身的标记。 (就我个人而言,我不太喜欢这种风格,尤其是像这些简单的片段,但每个人都有自己的风格。)在这种情况下,您应该将它们显式声明为 fragment ,以便它们不会作为 token 进行匹配:

fragment Letter     : [a-zA-Z] ;
fragment Digit : [0-9] ;
fragment Hex_Digit : [a-fA-F0-9] ;
...

然后将它们放在语法中的哪个位置并不重要。

参见https://theantlrguy.atlassian.net/wiki/display/ANTLR4/Lexer+Rules

关于java - ANTLR 中解析输入时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28634928/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com