我正在尝试为QuickBasic创建一个解析器,这是我获取注释的尝试:
grammar QuickBasic;
options
{
language = 'CSharp2';
output = AST;
}
tokens
{
COMMENT;
}
parse
: .* EOF
;
// DOESN'T WORK
Comment
: R E M t=~('\n')* { Text = $t; } -> ^(COMMENT $t)
| Quote t=~('\n')* { Text = $t; } -> ^(COMMENT $t)
;
Space
: (' ' | '\t' | '\r' | '\n' | '\u000C') { Skip(); }
;
fragment Quote : '\'';
fragment E : 'E' | 'e';
fragment M : 'M' | 'm';
fragment R : 'R' | 'r';即使我只使用token注释重写,而不使用其他注释,我仍然会得到相同的错误。
// It DOESN'T WORK EITHER
Comment
: (R E M | Quote) ~('\n')* -> ^(COMMENT)
;如果我放弃重写,它会起作用:
// THIS WORKS
Comment
: (R E M | Quote) ~('\n')*
;发布于 2012-06-01 20:26:44
重写规则只适用于解析器规则,而不适用于词法分析器规则。而且t=~('\n')*只会导致最后一个非换行符被存储在t-label中,所以这无论如何都不会起作用。
但是为什么不一起跳过这些Comment令牌呢?如果将它们留在令牌流中,则需要在所有解析器规则(其中Comment令牌有效出现)中考虑Comment令牌:这不是您想要的东西,对吧?
要跳过,只需在规则末尾调用Skip():
Comment
: R E M ~('\r' | '\n')* { Skip(); }
| Quote ~('\r' | '\n')* { Skip(); }
;或者更简洁:
Comment
: (Quote | R E M) ~('\r' | '\n')* { Skip(); }
;然而,如果你真的热衷于将Comment标记留在流中,并去掉"rem"或评论中的引用,那么可以这样做:
Comment
: (Quote | R E M) t=NonLineBreaks { Text = $t.text; }
;
fragment NonLineBreaks : ~('\r' | '\n')+;然后,您还可以创建一个解析器规则,该规则创建一个以COMMENT为根的AST (尽管我看不出使用Comment有什么好处):
comment
: Comment -> ^(COMMENT Comment)
;https://stackoverflow.com/questions/10850007
复制相似问题