我正在尝试为 R6RS 编写词法分析器/解析器,但我遇到了数据跳过评论
这是我的词法分析器/解析器规则的一部分:
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: '#;' datum -> skip
。不幸的是,解析器规则不允许->skip
. 两者都SKIPDATUM: '#;' datum -> skip
不起作用,因为词法分析器规则不能引用解析器规则。
在我看来,虽然“注释掉”是词法分析器的责任,而“构造数据”是解析器的责任,但#;
两者都需要规则。
这是我目前的解决方案:
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*
有没有更好的解决方案?提前致谢。