数据跳过注释&引用;在使用ANTLR4为R6RS创建解析器时

数据跳过注释&引用;在使用ANTLR4为R6RS创建解析器时,antlr4,r6rs,Antlr4,R6rs,我正试图为R6RS编写lexer/parser,但我被数据跳过注释所困扰 以下是我的lexer/parser规则的一部分: BOOLEAN: '#t' | '#f' | '#T' | '#F'; NUMBER: DIGIT+; // TODO: incomplete CHAR: '#\\' CHARNAME | '#\\x' HEXDIGIT+ | '#\\' . ; STRING: '"' STRELEMENT* '"'; IDENTIFIER: INITIAL SUBSEQUENT* | P

我正试图为R6RS编写lexer/parser,但我被数据跳过注释所困扰

以下是我的lexer/parser规则的一部分:

BOOLEAN: '#t' | '#f' | '#T' | '#F';
NUMBER: DIGIT+; // TODO: incomplete
CHAR: '#\\' CHARNAME | '#\\x' HEXDIGIT+ | '#\\' . ;
STRING: '"' STRELEMENT* '"';
IDENTIFIER: INITIAL SUBSEQUENT* | PERCULIAR_ID;

COMMENT: (';' .*? LINE_ENDING | '#!r6rs' ) -> skip;
NESTED_COMMENT: '#|' (NESTED_COMMENT | ~[#|] | ('|' ~'#') | ('#' ~'|') )* '|#' -> skip;

datum: lexemeDatum
     | compoundDatum;
compoundDatum: list
             | vector
             | bytevector;

// (rest omitted...)
现在,我想像
skipDatum:“#”基准->跳过
。不幸的是,解析器规则不允许跳过。都不是
SKIPDATUM:“#”datum->skip
将起作用,因为lexer规则不能引用解析器规则

在我看来,虽然“注释掉”是lexer的责任,“构建数据”是解析器的责任,但是关于
#两者都需要

以下是我当前的解决方案:

skipDatum: '#;' datum;

list: '(' (datum|skipDatum)* ')' #ProperListDatum
    | '[' (datum|skipDatum)* ']' #ProperListDatum
    | '(' skipDatum* datum (datum|skipDatum)* '.' skipDatum* datum skipDatum* ')' #ImproperListDatum
    | '[' skipDatum* datum (datum|skipDatum)* '.' skipDatum* datum skipDatum* ']' #ImproperListDatum
当它工作时,它看起来很丑陋;如果我真的想使用
datum
编写规则,我总是必须像
skipDatum*datum skipDatum*


有没有更好的解决办法?提前谢谢。

你可以用这样的东西

datum
    :   SKIP_DATUM? ...
    ;

SKIP_DATUM : '#;';
这将要求您在每次在生成的代码中使用
DatumContext
时执行以下检查,同时简化语法

if (ctx.SKIP_DATUM() != null) {
    // handle skipped datum here (return?)
}

虽然这似乎有效,但我们似乎将“丑陋”转移到了访客类。在我继续寻找更好的方法的同时,我将尝试这种方法。谢谢你的回答。我决定在解析器规则方面继续做“复杂的工作”,但要借助如下谓词:
list:'['(d1+=datum | skipDatum)+'。(d2+=datum | skipDatum)+']{$d1.size()>0&$d2.size()==1}#不正确的列表数据
。我没有注意到我可以在规则文件中插入一些“代码”。虽然我没有听从你的建议,但谢谢你的回答。