如何修改Jison解析器以保留尾随注释并忽略整行注释
如何修改Jison代码以保留尾随注释并正确解析标识符?
首先咱们拆解下问题根源:你原来的词法规则直接把所有--开头的内容都跳过了,不管它是跟在标识符后面的有效尾随注释,还是其他需要忽略的注释。要实现需求,得从词法规则的优先级与定义、语法规则的扩展两方面入手。
修改步骤详解
1. 调整词法分析器(Lex部分)
Jison的词法规则是按顺序匹配的,优先级从上到下,所以我们得先区分「行注释」和「尾随注释」:
- 先匹配行注释:整行(或行首带空白)以
--开头的内容,直接跳过; - 然后匹配尾随注释:匹配
--开头到下一个--之前的内容(刚好符合你要保留-- not to ignore this、忽略后续-- This must be ignored的需求),返回TRAILING_COMMENT令牌; - 最后处理标识符、空白等其他内容。
修改后的Lex规则:
%lex %% ^(\s*)--.*$ /* 跳过整行注释(行首含空白的--注释也会被匹配) */ --([^-]|-[^-])* return 'TRAILING_COMMENT' /* 匹配尾随注释,到下一个--前停止 */ [a-zA-Z]+ return 'IDENTIFIER' \s+ /* 跳过标识符之间的空白 */ <<EOF>> return 'EOF' . /* 跳过其他无效字符 */ /lex
2. 扩展语法分析器(Grammar部分)
原来的语法只处理单独的IDENTIFIER,现在需要添加规则,允许标识符后面紧跟尾随注释的组合,这样解析器就能把两者拼接输出:
修改后的Grammar规则:
%start expressions %% expressions : expressions EOF | expressions expression | expression {;} ; expression : IDENTIFIER {console.log($1); $$ = $1;} | IDENTIFIER TRAILING_COMMENT {console.log(`${$1} ${$2}`); $$ = `${$1} ${$2}`;} ;
完整修改后的Jison代码
%lex %% ^(\s*)--.*$ /* 跳过整行注释 */ --([^-]|-[^-])* return 'TRAILING_COMMENT' /* 匹配尾随注释(--到下一个--前) */ [a-zA-Z]+ return 'IDENTIFIER' \s+ /* 跳过空白字符 */ <<EOF>> return 'EOF' . /* 跳过其他无效字符 */ /lex %start expressions %% expressions : expressions EOF | expressions expression | expression {;} ; expression : IDENTIFIER {console.log($1); $$ = $1;} | IDENTIFIER TRAILING_COMMENT {console.log(`${$1} ${$2}`); $$ = `${$1} ${$2}`;} ;
为什么这样修改能生效?
- 词法规则顺序:先处理行注释,避免把整行注释误判为尾随注释;然后优先匹配尾随注释,确保标识符后的
--内容被识别为有效令牌,而不是被跳过; - 语法规则扩展:新增了标识符+尾随注释的组合规则,让解析器能识别并输出包含尾随注释的完整内容;
- 尾随注释正则:
--([^-]|-[^-])*确保只匹配到下一个--之前的内容,完美符合你期望的输出结果。
内容的提问来源于stack exchange,提问作者Jeon
相关产品推荐
相关产品推荐

