我正在尝试使用以下条件进行多行注释:
- 以
'''
开始,以'''
结束 - 内部不能正好包含三个
'''
,例如:'''''' Correct '''''''' Correct '''a'a''a''''a''' Correct ''''''''' Incorrect '''a'''a''' Incorrect
这是我的近似,但我无法对此做出正确的表达式:
'''([^']|'[^']|''[^']|''''+[^'])*'''+
简单的解决方案是使用启动条件。(请注意,这并不能传递给您的所有测试用例,因为我认为问题描述不明确。请参阅下文。(
在下文中,我假设您想要返回匹配的令牌,并且您使用的是yacc/bison生成的解析器,该解析器包括作为并集类型之一的char* str
。启动条件块是Flex扩展;在使用其他lex衍生物的不太可能的情况下,您需要每行写一个模式,每个模式都带有<SC_TRIPLE_QUOTE>
前缀(并且与模式之间没有空格(。
%x SC_TRIPLE_QUOTE
%%
''' { BEGIN(TRIPLE_QUOTE); }
<TRIPLE_QUOTE>{
''' { yylval.str = strndup(yytext, yyleng - 3);
BEGIN(INITIAL);
return STRING_LITERAL;
}
[^']+ |
''?/[^'] |
''''+ { yymore(); }
<<EOF>> { yyerror("Unterminated triple-quoted string");
return 0;
}
}
我希望这或多或少是不言自明的。起始条件内的四个模式匹配'''
终止符、除'
之外的任何字符序列、不超过两个'
和至少四个'
。CCD_ 10使得各个匹配被累积。对strndup
的调用不包括分隔符。
注:
上面的代码不会提供您对第二个示例的期望,因为我认为这是不可能的(或者,您需要更清楚地了解两个可能的分析中哪一个是正确的,以及为什么(。考虑可能的评论:
'''a'''
'''a''''
'''a''''a'''
根据您的描述(以及第三个示例(,第三个应该与内部值a''''a
匹配,因为''''
超过了三个引号。但是根据您的第二个示例(稍作修改(,第二个应该与内部值'
匹配,因为最后的'''
被用作终止符。问题是,这两种可能的解释应该如何区分?换句话说,词法扫描程序有什么线索,在第二种情况下,令牌在'''
结束,而在第三种情况下则没有?由于这两者都是输入流的一部分,因此后面可能有任意文本。由于这些应该是多行注释,因此没有先验的理由相信换行符不是标记的一部分。
因此,我武断地选择了该选择哪种解释。我本可以做出另一个任意的选择,但如果换一个例子就行不通了。