单个字符的 Antlr4 令牌歧义
Antlr4 token ambiguity for single character
我对规则 mnemonic_format
有疑问。
而不是识别像 A100 这样的简单文本,它给出了以下错误:
mismatched input 'A100' expecting 'A'
语法是:
grammar SimpleMathGrammar;
INTEGER : [0-9]+;
FLOAT : [0-9]+ '.' [0-9]+;
ADD : '+';
SUB : '-';
DOT : '.';
AND : 'AND';
BACKSLASH : '\';
fragment SINGLELETTER : ( 'a'..'z' | 'A'..'Z');
fragment LOWERCASE : 'a'..'z';
fragment UNDERSCORE : '_';
fragment DOLLAR : '$';
fragment NUMBER : '0'..'9';
VARIABLENAME
: SINGLELETTER
| (SINGLELETTER|UNDERSCORE) (SINGLELETTER | UNDERSCORE | DOLLAR | NUMBER)*;
HASH : '#';
/* PARSER */
operation
: (INTEGER | FLOAT) ADD (INTEGER | FLOAT)
| (INTEGER | FLOAT) SUB (INTEGER | FLOAT);
operation_with_backslash : BACKSLASH operation BACKSLASH;
mnemonic: HASH VARIABLENAME HASH;
mnemonic_format
// Example: A100
: 'A' INTEGER;
至此,我知道令牌VARIABLENAME
不应该包含字符A(如果我错了请纠正我)
那么我可以做些什么来在不同的规则中包含单个字符(o 固定序列)? (哪个是我的错误?)
编辑:我在以下标记案例中找到了问题的根源(通过删除所有其他标记和规则):
VARIABLENAME: (SINGLELETTER|UNDERSCORE) (SINGLELETTER | UNDERSCORE | DOLLAR | NUMBER)*;
那么我如何创建一个 token 或 lexer 规则 来为我提供 检测一些通用的基础文本(如Class名称或变量名称)由同时创建规则 其中我必须 接受固定的字符序列?
好的,
诀窍是令牌 VARIABLENAME
的 "general scope"。
换句话说,令牌过于通用。
在我的例子中 sub-condition VARIABLENAME: SINGLELETTER NUMBER*
crash/collide with the condition mnemonic_format: 'A' INTEGER
(实际上,我可以用 VARIABLENAME
或 mnemonic_format
创建字符串 A100,这会造成 歧义 )
所以我"specialize" VARIABLENAME
接受一个前缀,例如:
VARIABLENAME
: HASH (SINGLELETTER|UNDERSCORE)(SINGLELETTER|UNDERSCORE|DOLLAR|NUMBER)*
| 'class ' (SINGLELETTER|UNDERSCORE)(SINGLELETTER|UNDERSCORE|DOLLAR|NUMBER)*
...
这应该可以避免令牌和规则之间的歧义
我对规则 mnemonic_format
有疑问。
而不是识别像 A100 这样的简单文本,它给出了以下错误:
mismatched input 'A100' expecting 'A'
语法是:
grammar SimpleMathGrammar;
INTEGER : [0-9]+;
FLOAT : [0-9]+ '.' [0-9]+;
ADD : '+';
SUB : '-';
DOT : '.';
AND : 'AND';
BACKSLASH : '\';
fragment SINGLELETTER : ( 'a'..'z' | 'A'..'Z');
fragment LOWERCASE : 'a'..'z';
fragment UNDERSCORE : '_';
fragment DOLLAR : '$';
fragment NUMBER : '0'..'9';
VARIABLENAME
: SINGLELETTER
| (SINGLELETTER|UNDERSCORE) (SINGLELETTER | UNDERSCORE | DOLLAR | NUMBER)*;
HASH : '#';
/* PARSER */
operation
: (INTEGER | FLOAT) ADD (INTEGER | FLOAT)
| (INTEGER | FLOAT) SUB (INTEGER | FLOAT);
operation_with_backslash : BACKSLASH operation BACKSLASH;
mnemonic: HASH VARIABLENAME HASH;
mnemonic_format
// Example: A100
: 'A' INTEGER;
至此,我知道令牌VARIABLENAME
不应该包含字符A(如果我错了请纠正我)
那么我可以做些什么来在不同的规则中包含单个字符(o 固定序列)? (哪个是我的错误?)
编辑:我在以下标记案例中找到了问题的根源(通过删除所有其他标记和规则):
VARIABLENAME: (SINGLELETTER|UNDERSCORE) (SINGLELETTER | UNDERSCORE | DOLLAR | NUMBER)*;
那么我如何创建一个 token 或 lexer 规则 来为我提供 检测一些通用的基础文本(如Class名称或变量名称)由同时创建规则 其中我必须 接受固定的字符序列?
好的,
诀窍是令牌 VARIABLENAME
的 "general scope"。
换句话说,令牌过于通用。
在我的例子中 sub-condition VARIABLENAME: SINGLELETTER NUMBER*
crash/collide with the condition mnemonic_format: 'A' INTEGER
(实际上,我可以用 VARIABLENAME
或 mnemonic_format
创建字符串 A100,这会造成 歧义 )
所以我"specialize" VARIABLENAME
接受一个前缀,例如:
VARIABLENAME
: HASH (SINGLELETTER|UNDERSCORE)(SINGLELETTER|UNDERSCORE|DOLLAR|NUMBER)*
| 'class ' (SINGLELETTER|UNDERSCORE)(SINGLELETTER|UNDERSCORE|DOLLAR|NUMBER)*
...
这应该可以避免令牌和规则之间的歧义