Parsing 具有简单语法的Antlr MissingTokenException
我有我认为是世界上最简单的语法,解析文件系统路径,格式为dir1/dir2/filename(没有前导/)。我删去了一些细节,得到了一个小样本,显示了这个问题Parsing 具有简单语法的Antlr MissingTokenException,parsing,antlr,lexer,Parsing,Antlr,Lexer,我有我认为是世界上最简单的语法,解析文件系统路径,格式为dir1/dir2/filename(没有前导/)。我删去了一些细节,得到了一个小样本,显示了这个问题 compilationUnit : relativePath; identifier: IdentifierStart IdentifierPart*; relativePath : identifier (SLASH identifier)*; SLASH : '/'; fragment IdentifierPart
compilationUnit : relativePath;
identifier: IdentifierStart IdentifierPart*;
relativePath : identifier (SLASH identifier)*;
SLASH : '/';
fragment IdentifierPart : 'a'..'z' | 'A'..'Z' | '_' | '0'..'9';
fragment IdentifierStart : 'a'..'z' | 'A'..'Z' | '_';
如果我给它输入foo/aa/bb之类的内容,我会得到一个MissingTokenException。它标识一个标识符,然后得到斜杠,然后我得到一个挂起标识符的MissingTokenException。一定是我错过了一些基本的东西,但是什么呢 将关键字
片段
放在lexer规则前面时,不能在解析器规则中使用此规则。片段
只能在其他lexer规则中使用。这些规则永远不会单独成为令牌,它们只能作为其他令牌(其他lexer规则)的一部分使用
换句话说:从语法中删除这些片段关键字:
// parser rules
compilationUnit : relativePath;
relativePath : identifier (SLASH identifier)*;
identifier : IdentifierStart (IdentifierStart | Digit)*;
// lexer rules
SLASH : '/';
IdentifierStart : 'a'..'z' | 'A'..'Z' | '_';
Digit : '0'..'9';
但是,也可以将相对路径设置为单个标记,在这种情况下,您可以保留片段
关键字,但必须将一些解析器规则设置为lexer规则,如下所示:
// parser rule
compilationUnit : RelativePath;
// lexer rules
RelativePath : Identifier ('/' Identifier)*;
fragment Identifier : IdentifierStart IdentifierPart*;
fragment IdentifierPart : 'a'..'z' | 'A'..'Z' | '_' | '0'..'9';
fragment IdentifierStart : 'a'..'z' | 'A'..'Z' | '_';
但是,由于RelativePath与单个标识符
匹配,因此永远不会为解析器创建标识符
标记。因此,标识符
也应该是片段
。所以,也许这不是你想要的。我最后在antlr列表上问了这个问题。提供的解释是,通过大写将标识符转换为解析器规则应该可以解决问题,因为解析器永远不会看到IdenifierStart和identifiernd片段。在lexer中运行规则解决了这个问题。@seven,我不明白你为什么在那里问:我已经给出了答案,没有?