Lex - 字符串中的双引号

时间:2015-09-16 20:55:52

标签: regex string lex

我的lex语法包含双引号字符串的规则:

...
%x DOUBLEQUOTE
...
%%
"\""                { yylval->string = NULL; BEGIN(DOUBLEQUOTE); }
<DOUBLEQUOTE> {
    "\n"            {
                        /* reset column counter on new line */
                        PARSER->linepos = 0;
                        (PARSER->linenum)++;
                        expr_parser_append_string(PARSER, &(yylval->string), yytext);
                    }
    [^\"\n]+        { expr_parser_append_string(PARSER, &(yylval->string), yytext); }
    "\\\""          { expr_parser_append_string(PARSER, &(yylval->string), yytext); }
    "\""            {
                        BEGIN(INITIAL);
                        if ( yylval->string != NULL )
                            string_unescape_c(yylval->string);
                        return ( TOKEN_STRING );
                    }
}

以某种方式,转义序列 \“仅在字符串的开头匹配。如果 \”在字符串的后面出现,则它看起来像字符 \ 分开匹配。

例如:

  1. 通过:"\" "

  2. 失败:" \" "

  3. 失败:"This is string example: \"a string inside of string\""

  4. 为什么转义序列 \“与字符"\\\""在后​​面的字符串中出现时不匹配?

2 个答案:

答案 0 :(得分:0)

[^\"\n]+        { expr_parser_append_string(PARSER, &(yylval->string), yytext); }

除了引号和换行符之外,此规则还应排除反斜杠。或者它应该被移动,因此它在列表中排在最后。

答案 1 :(得分:0)

如果反斜杠不是引用字符串中的第一个字符,则反斜杠将在某个标记的末尾匹配。例如:

 "abc\"def"
  ^^^^       First token, longest match of [^"\n]+
      ^      Terminates quoted string

所以你也需要排除反斜杠。但是一旦你这样做,你需要提供一个匹配反斜杠转义的模式,而不仅仅是反斜杠转义引号。所以我建议:

<DOUBLEQUOTE>{
  \\?\n              { /* Handle newline */ }
  ([^"\\\n]|\\.)+    { expr_parser_append_string(PARSER,
                                                 &yylval->string,
                                                 yytext); }
  \"                 { BEGIN(INITIAL); ... }
}

注意:我在第一个模式的开头添加了一个可选的反斜杠,以便处理反斜杠紧接在换行符之前的情况。第二种模式中的.\\.)与换行符不匹配,否则根本不会识别反斜杠换行符。