如何使用 lex 识别引号以外的字符串?

How can I use lex to identify strings other than the quotation marks?

真正的 lex 菜鸟。我正在尝试使用正则表达式来识别 printf() 中的字符串,例如 printf("hello world!"); ,但最好的结果只是 "hello world!" ,我不想要双引号,只是你好世界!我该怎么办?

到目前为止的正则表达式是:("\"")(.)*("\"")

匹配字符串文字的良好正则表达式是:

["]([^"]|\(.|\n))*["]
["]([^"\n]|\(.|\n))*["]

第一个在多行字符串上失败;第二个接受他们。在这两种情况下,不匹配的引号都不会匹配,您是否需要使用其他模式处理这些错误输入。两种模式都接受反斜杠转义(包括 backslash-escaped 换行符)而不尝试解释它们。大多数 real-life 词法扫描器都希望以某种方式处理反斜杠转义序列,通常是将它们转换为它们所代表的字符。但这需要不同的机制,这超出了这个问题的范围。

如您所见,匹配项包含引号,因此您需要将其删除。由于您通常必须复制匹配的令牌(因为 yytext 的内容将在下次调用扫描器时被覆盖),只需复制您感兴趣的匹配部分即可轻松完成.

请记住,yyleng 是令牌的长度。因此,您想要的子字符串从 yytext + 1 开始(跳过开头引号)并继续 yyleng - 2 个字符(不包括任何引号):

["]([^"]|\(.|\n))*["]  {
          yylval.str = malloc(yyleng -1);
          memcpy(yylval.str, yytext + 1, yyleng - 2);
          yylval.str[yyleng - 2] = 0;
        }

当然还有其他的写法,但它们都是相似的。