我如何使用lex来识别除引号之外的字符串?

时间:2019-05-21 06:53:04

标签: string lex

真正的lex新秀。我正在尝试使用正则表达式来标识printf()之类的printf("hello world!");中的字符串,但是最好的结果只是“ hello world!”。 ,我不希望双引号,只是您好!我该怎么办?

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

1 个答案:

答案 0 :(得分:1)

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

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

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

您已经发现,匹配项包含引号,因此您将希望删除它们。由于您通常必须复制匹配的令牌(由于yytext的内容将在下次调用扫描程序时被覆盖),因此只需复制您感兴趣的匹配部分即可轻松完成

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

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

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