ANTLR 匹配标识符但不匹配保留关键字
ANTLR match identifier but not reserved keywords
我正在尝试使用不同的符号来匹配复数,其中之一使用 cis
函数:MODULUS cis
PHASE
问题是我的标识符规则匹配 cis
以及它后面的数字的开头,因为它比 CIS
令牌本身大,所以它总是 returns标识符令牌类型。我怎样才能避免这种情况?
这是语法:
grammar Sandbox;
input : number? CIS UNSIGNED
| IDENTIFIER
;
number : FLOAT
| UFLOAT
| UINT
| INT
;
fragment DIGIT : [0-9] ;
UFLOAT : UINT (DOT UINT? | 'f') ;
FLOAT : SUB UFLOAT ;
UINT : DIGITS ;
INT : SUB UINT ;
UNSIGNED : UFLOAT
| UINT
;
DIGITS : DIGIT+ ;
// Specific lexer rules
CIS : 'cis' ;
SUB : '-' ;
DOT : '.' ;
WS : [ \t]+ -> skip ;
NEWLINE : '\r'? '\n' ;
IDENTIFIER : [a-zA-Z_]+[a-zA-Z0-9_]* ; // has to be after complex so i or cis doesn't match this first
编辑:
我试图解析的输入是复杂的 1+i
但使用它各自的模数和相位是这样的:1.4142135623730951cis0.7853981633974483
我的实际问题是 IDENTIFIER 规则匹配 cis0
而不是仅仅匹配 CIS 词法分析器规则,即使它在它之前定义。
我隐约知道 ANTLR 根据最大匹配选择规则,但在这种情况下我想避免这种情况 =o.
我把它放在这里是因为我认为这可能是一个潜在的解决方案,尽管我宁愿不必使用语义谓词,因为它将我的语法与 target/specific 语言联系起来 =/(我以前从未使用过它们,所以我不确定是否还有其他注意事项):
IDENTIFIER: [a-zA-Z_][a-zA-Z0-9_]* { identifierIsNotReserved() }?;
然后我们只需要实现 identifierIsNotReserved
方法来检查标识符规则是否使用了保留关键字,如果是则阻止应用该规则。我引用:
A semantic predicate is a block of arbitrary code in the target language surrounded by {...}?, which evaluates to a boolean value. If the returned value is false, the lexer rule is skipped.
编辑:忘记添加对我在哪里找到它的引用,这里是:
https://riptutorial.com/antlr/example/11237/actions-and-semantic-predicates
我在这里看到两个解决方案:
- 使复数成为单个词法分析器规则:
COMPLEX: (FLOAT | UFLOAT | UINT | INT) WS* CIS WS* UNSIGNED;
这将比标识符或 pur CIS 关键字长(因此首先匹配)。
- A
cis
secquence 是一个关键字,当它跟在一个数字之后(它们之间有可选的空格),对吗?因此,如果该条件为真,您可以在谓词中进行回顾(LA(-1)
以拒绝 cis
作为标识符。
我更喜欢解决方案 1,因为约定是单个实体(复数是,如浮点数或字符串,单个逻辑实体)在词法分析器规则中完全匹配,而不是在解析器规则。
我正在尝试使用不同的符号来匹配复数,其中之一使用 cis
函数:MODULUS cis
PHASE
问题是我的标识符规则匹配 cis
以及它后面的数字的开头,因为它比 CIS
令牌本身大,所以它总是 returns标识符令牌类型。我怎样才能避免这种情况?
这是语法:
grammar Sandbox;
input : number? CIS UNSIGNED
| IDENTIFIER
;
number : FLOAT
| UFLOAT
| UINT
| INT
;
fragment DIGIT : [0-9] ;
UFLOAT : UINT (DOT UINT? | 'f') ;
FLOAT : SUB UFLOAT ;
UINT : DIGITS ;
INT : SUB UINT ;
UNSIGNED : UFLOAT
| UINT
;
DIGITS : DIGIT+ ;
// Specific lexer rules
CIS : 'cis' ;
SUB : '-' ;
DOT : '.' ;
WS : [ \t]+ -> skip ;
NEWLINE : '\r'? '\n' ;
IDENTIFIER : [a-zA-Z_]+[a-zA-Z0-9_]* ; // has to be after complex so i or cis doesn't match this first
编辑:
我试图解析的输入是复杂的 1+i
但使用它各自的模数和相位是这样的:1.4142135623730951cis0.7853981633974483
我的实际问题是 IDENTIFIER 规则匹配 cis0
而不是仅仅匹配 CIS 词法分析器规则,即使它在它之前定义。
我隐约知道 ANTLR 根据最大匹配选择规则,但在这种情况下我想避免这种情况 =o.
我把它放在这里是因为我认为这可能是一个潜在的解决方案,尽管我宁愿不必使用语义谓词,因为它将我的语法与 target/specific 语言联系起来 =/(我以前从未使用过它们,所以我不确定是否还有其他注意事项):
IDENTIFIER: [a-zA-Z_][a-zA-Z0-9_]* { identifierIsNotReserved() }?;
然后我们只需要实现 identifierIsNotReserved
方法来检查标识符规则是否使用了保留关键字,如果是则阻止应用该规则。我引用:
A semantic predicate is a block of arbitrary code in the target language surrounded by {...}?, which evaluates to a boolean value. If the returned value is false, the lexer rule is skipped.
编辑:忘记添加对我在哪里找到它的引用,这里是: https://riptutorial.com/antlr/example/11237/actions-and-semantic-predicates
我在这里看到两个解决方案:
- 使复数成为单个词法分析器规则:
COMPLEX: (FLOAT | UFLOAT | UINT | INT) WS* CIS WS* UNSIGNED;
这将比标识符或 pur CIS 关键字长(因此首先匹配)。
- A
cis
secquence 是一个关键字,当它跟在一个数字之后(它们之间有可选的空格),对吗?因此,如果该条件为真,您可以在谓词中进行回顾(LA(-1)
以拒绝cis
作为标识符。
我更喜欢解决方案 1,因为约定是单个实体(复数是,如浮点数或字符串,单个逻辑实体)在词法分析器规则中完全匹配,而不是在解析器规则。