使用 flex 将 Python 多行字符串与转义字符匹配



我想知道如何将python多行注释与flex匹配。而且我遇到了一些麻烦,以下内容在正则表达式上工作正常,但无法被flex识别,我不知道如何解决。

"""[^"\]*(?:(?:\.|"{1,2}(?!"))[^"\]*)*"""

以前,我使用:

["]{3}(\["])*(["]{0,2}[^"](\["])*)*["]{3}

它可以检测以下评论:

"""A"""A"""

但是,它不能处理多个\,例如

'''A\\'''A=B'''C'''

将其视为一个整体,而不是:

'''A\\'''  (comment)   
A=B     
'''C'''(comment) 

你可以用一个正则表达式识别Python长字符串。它并不漂亮,但我相信它有效:

["]{3}(["]{0,2}([^\"]|\(.|n)))*["]{3}

这与您的原始正则表达式非常相似,但它不会尝试将其反斜杠处理限制为 " ,以便它可以正确地将\标识为反斜杠字符。

一个可能更容易阅读(但速度稍慢)的解决方案是使用启动条件。在这里,我使用 yymore() 创建一个不包含"""分隔符的单个标记,但生产代码可能会试图解释 Python 的各种反斜杠转义。(正是这种需求促使使用开始条件,而不是试图用单个正则表达式识别整个字符串。

%x SC_LONGSTRING
%%
["]{3}     BEGIN(SC_LONGSTRING);
<SC_LONGSTRING>{
  [^\"]+  yymore();
  \(.|n) yymore();
  ["]["]?  yymore();
  ["]{3}   { BEGIN(INITIAL);
             yylval.str = malloc(yyleng - 2);
             memcpy(yylval.str, yytext, yyleng - 3);
             yylval.str[yyleng - 3] = 0;
             return TOKEN_STRING;
           }
}

最新更新