否定未能匹配antlr4中的运算符

否定未能匹配antlr4中的运算符,antlr4,Antlr4,我有以下antlr4语法: grammar nota; word: WORD; WORD: ~'a'; //match anything that isn't an 'a' 如上所述,这将否定单个给定字符或字符范围的字符集 然后我尝试解析一些测试用例文本(每个测试用例输入一个字符): a预期失败 b预期成功 $预期成功 +意外失败 =意外失败 §预期成功 \预期成功 /意外失败 ~预期成功 如果有关系,我将使用nodejs的antlr4ts 0.5.0-alpha.4。 例如,默认错误侦听器打

我有以下antlr4语法:

grammar nota;
word: WORD;
WORD: ~'a'; //match anything that isn't an 'a'
如上所述,这将否定单个给定字符或字符范围的字符集

然后我尝试解析一些测试用例文本(每个测试用例输入一个字符):
a
预期失败
b
预期成功
$
预期成功
+
意外失败

=
意外失败

§
预期成功
\
预期成功
/
意外失败

~
预期成功

如果有关系,我将使用nodejs的antlr4ts 0.5.0-alpha.4。
例如,默认错误侦听器打印

第1行:0不匹配的输入“+”应为单词

我是否误解了antlr的
~
操作员?
这是一个应该报告的错误吗?我没有看到任何东西

编辑:为了解决这个错误,我将语法改为
WORD:'+'| ~'a',但由于某种奇怪的原因,它也无法匹配
+

这也无法解析
+

grammar nota;
word: WORD | OPERATORS;
OPERATORS: '+'|'-'|'*'|'/'|'=';
WORD: ~'a';
grammar nota;
word: WORD | '+'|'-'|'*'|'/'|'=';
WORD: ~'a';
这将成功解析
+

grammar nota;
word: WORD | OPERATORS;
OPERATORS: '+'|'-'|'*'|'/'|'=';
WORD: ~'a';
grammar nota;
word: WORD | '+'|'-'|'*'|'/'|'=';
WORD: ~'a';

我无法用
0.5.0-alpha.4
重现这一点

考虑到语法:

grammar nota;
word: WORD;
WORD: ~'a';
运行此代码:

import { CharStreams, CommonTokenStream } from 'antlr4ts';
import { notaLexer } from './parser/notaLexer';
import { notaParser } from './parser/notaParser';

const lexer = new notaLexer(CharStreams.fromString("+"));
const parser = new notaParser(new CommonTokenStream(lexer));
const root = parser.word();

console.log(root.toInfoString(parser));
不会产生任何错误或警告

我怀疑你没有发布完整的语法。很可能,解析器规则中有一些
'+'
文本,或者
'+'
已经由
单词
规则之前定义的词法规则匹配。lexer的工作方式非常简单:

  • 尝试为每个规则匹配尽可能多的字符
  • 如果两个或多个规则匹配相同数量的字符,则让第一个定义的规则“赢”
  • 所以,如果你有这样的规则:

    word: WORD;
    PLUS : '+';
    WORD: ~'a';
    

    然后输入的
    “+”
    将始终成为
    加上
    标记。即使解析器尝试匹配
    单词
    标记。

    我也无法使用
    0.5.0-alpha.4
    复制该标记

    考虑到语法:

    grammar nota;
    word: WORD;
    WORD: ~'a';
    
    运行此代码:

    import { CharStreams, CommonTokenStream } from 'antlr4ts';
    import { notaLexer } from './parser/notaLexer';
    import { notaParser } from './parser/notaParser';
    
    const lexer = new notaLexer(CharStreams.fromString("+"));
    const parser = new notaParser(new CommonTokenStream(lexer));
    const root = parser.word();
    
    console.log(root.toInfoString(parser));
    
    不会产生任何错误或警告

    我怀疑你没有发布完整的语法。很可能,解析器规则中有一些
    '+'
    文本,或者
    '+'
    已经由
    单词
    规则之前定义的词法规则匹配。lexer的工作方式非常简单:

  • 尝试为每个规则匹配尽可能多的字符
  • 如果两个或多个规则匹配相同数量的字符,则让第一个定义的规则“赢”
  • 所以,如果你有这样的规则:

    word: WORD;
    PLUS : '+';
    WORD: ~'a';
    

    然后输入的
    “+”
    将始终成为
    加上
    标记。即使解析器尝试匹配
    单词
    标记。

    正如Java、C#和JavaScript(使用4.9.2-snapshot和NodeJs 14.15.4)所预期的那样,解析下面的第一个语法和示例。我认为TS目标还没有完成。第一个语法和示例就在Java、C#和JavaScript(使用4.9.2-snapshot和NodeJs 14.15.4)预期的解析下面。我认为TS目标尚未完成。对于未来的访问者:它确实是Antlr属性,与TypeScript或AntlR4T无关<代码>单词:~'a'
    将与
    '+'
    匹配,直到添加
    expr:expr'+'expr
    使Antlr使用优先于
    WORD
    的未命名令牌
    '+'
    定义一个特殊词法规则。您这样提到的每个字符都会自动从
    WORD
    中排除,而且您也不能执行
    WORD:~'a'|'+'
    ,因为lexer仍然必须选择要使用的标记。但是,您可以执行
    word:word |'+'
    并记住在出现所有临时标记时添加它们,这并不理想。对于未来的访问者:它确实是Antlr属性,与TypeScript或AntlR4T无关<代码>单词:~'a'
    将与
    '+'
    匹配,直到添加
    expr:expr'+'expr
    使Antlr使用优先于
    WORD
    的未命名令牌
    '+'
    定义一个特殊词法规则。您这样提到的每个字符都会自动从
    WORD
    中排除,而且您也不能执行
    WORD:~'a'|'+'
    ,因为lexer仍然必须选择要使用的标记。但是,您可以执行
    word:word |'+'
    并记住在出现临时标记时添加所有临时标记,这并不理想。