[英]match words with spaces as one token but disallow certain keyword tokens
我有以下令牌规则:
IF: 'IF' | 'if';
THEN: 'THEN' | 'then';
ELSE: 'ELSE' | 'else';
BINARYOPERATOR: 'AND' | 'and' | 'OR' | 'or';
NOT: 'NOT' | 'not';
WORD: (DIGIT* (LOWERCASE | UPPERCASE | WORDSYMBOL)) (LOWERCASE | UPPERCASE | DIGIT | WORDSYMBOL)*;
这行得通,像my variable
这样的东西以WORD WORD
形式出现。 我希望能够只拥有一个代表整个事物的令牌。
我把它挂在:
IF: 'IF' | 'if';
THEN: 'THEN' | 'then';
ELSE: 'ELSE' | 'else';
BINARYOPERATOR: 'AND' | 'and' | 'OR' | 'or';
NOT: 'NOT' | 'not';
WORD: (LOWERCASE | UPPERCASE | WORDSYMBOL)+ (' '* (LOWERCASE | UPPERCASE | WORDSYMBOL))*;
这解决了这个问题,但是它也捕获了我想分类为上述关键字标记的字符串。
例如if my variable then something
应该只是单个WORD
标记,它应该是IF WORD THEN WORD
。
我理解为什么要按原样对其进行标记(首选消耗更多输入的标记),但不确定如何更改行为。
不幸的是(对于您想做的事情),ANTLR 的标记化不是这样工作的。
(这更像是一个“合乎逻辑”的解释,而不是实际的实现)
当 ANTLR 评估 Lexer 规则时,它会尝试将每个规则与输入 stream 中的字符匹配,该输入 stream 中以当前 position 开头。
一旦它拥有所有匹配的输入序列,如果有一个序列比 rest 长,它将选择产生最长令牌的令牌类型。 这是您的WORD
规则将使用输入的地方,直到找到与WORD
中的字符不匹配的内容(如果它们与WORD
模式匹配,则将包括“slurping”关键字)。
(为了完整性)如果 Tokenizer 发现多个等长匹配,则在您的语法中匹配的第一个规则将是分配的 Token 类型。
您可能会通过以下方法获得成功:
假设: WORD
不能是您的语言关键字之一
WORD
规则位于所有关键字规则之后,以便它们优先。word: WORD+;
RULE
标记的任何地方都使用 parser rule word
。enterWord()
的侦听器并将所有WORD
合并为一个“单词”。 (您可以通过多种方式处理此步骤,但这是一种相当简单的方法)警告:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.