Lex - 字符串内的双引号
Lex - double quotation mark inside string
我有包含双引号字符串规则的 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 );
}
}
转义序列 \" 仅在字符串的开头匹配。如果 \" 出现在字符串的后面看起来字符 \ 和 " 分别匹配。
例如:
通过:"\" "
失败:" \" "
失败:"This is string example: \"a string inside of string\""
为什么转义序列 \" 出现在字符串的后面时与规则 "\\""
不匹配?
[^\"\n]+ { expr_parser_append_string(PARSER, &(yylval->string), yytext); }
除了引号和换行符之外,此规则还应排除反斜杠。或者应该将其移动到列表的最后。
如果反斜杠不是引用字符串中的第一个字符,那么反斜杠将在某些标记的末尾进行匹配。例如:
"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); ... }
}
注意:我在第一个模式的开头添加了一个可选的反斜杠,以处理反斜杠紧接在换行符之前的情况。第二个模式 (\.
) 中的 .
不会匹配换行符,否则反斜杠换行符根本无法识别。
我有包含双引号字符串规则的 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 );
}
}
转义序列 \" 仅在字符串的开头匹配。如果 \" 出现在字符串的后面看起来字符 \ 和 " 分别匹配。
例如:
通过:
"\" "
失败:
" \" "
失败:
"This is string example: \"a string inside of string\""
为什么转义序列 \" 出现在字符串的后面时与规则 "\\""
不匹配?
[^\"\n]+ { expr_parser_append_string(PARSER, &(yylval->string), yytext); }
除了引号和换行符之外,此规则还应排除反斜杠。或者应该将其移动到列表的最后。
如果反斜杠不是引用字符串中的第一个字符,那么反斜杠将在某些标记的末尾进行匹配。例如:
"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); ... }
}
注意:我在第一个模式的开头添加了一个可选的反斜杠,以处理反斜杠紧接在换行符之前的情况。第二个模式 (\.
) 中的 .
不会匹配换行符,否则反斜杠换行符根本无法识别。