有一个flex选项只能匹配整个单词吗?

时间:2014-09-04 22:23:46

标签: c regex flex-lexer lexical-analysis

我正在写一个词法分析器,我正在使用Flex根据自定义规则生成它。

我希望匹配以字母开头的排序标识符,然后可以包含字母或数字。所以我为他们写了以下模式:

[[:alpha:]][[:alnum:]]*

它工作得很好,生成的词法分析器可以完美地识别出模式,虽然它不仅匹配整个单词,而且还匹配该模式的所有外观。

例如,它会匹配输入“Text”和“9Text”(丢弃该初始值9)。

考虑以下简单的词法分析器,它接受如上所述的ID:

%{
#include <stdio.h>

#define LINE_END 1
#define ID       2

%}

/* Flex options: */
%option noinput
%option nounput
%option noyywrap
%option yylineno

/* Definitions: */
WHITESPACE  [ \t]
BLANK       {WHITESPACE}+
NEW_LINE    "\n"|"\r\n"
ID          [[:alpha:]][[:alnum:]_]*

%%

{NEW_LINE}        {printf("New line.\n"); return LINE_END;}
{BLANK}           {/* Blanks are skipped */}
{ID}              {printf("ID recognized: '%s'\n", yytext); return ID;}
.                 {fprintf(stderr, "ERROR: Invalid input in line %d: \"%s\"\n", yylineno, yytext);}

%%

int main(int argc, char **argv) {
   while (yylex() != 0);
   return 0;
}

编译并输入时,以下输入产生以下输出:

输入:

Test
9Test

输出:

Test
ID recognized: 'Test'
New line.
9Test
ERROR: Invalid input in line 2: "9"
ID recognized: 'Test'
New line.

有没有办法让flex匹配整个单词(例如由空格或自定义分隔符分隔,例如'('')')?

因为我可以编写一个排除以数字开头的ID的规则,但那些以“$ Test”或“&amp; Test”等符号开头的规则呢?我认为我不能列举所有可能的符号。

按照上面的示例,所需的输出将是:

Test
ID recognized: 'Test'
New line.
9Test
ERROR: Invalid input 2: "9Test"
New line.

3 个答案:

答案 0 :(得分:1)

你似乎一次要问两个问题。

  1. '整字'不是编程语言中公认的结构。词法和语法已经定义。只需实施它们。

  2. 在flex中处理非法或意外字符的最佳方法是根本不处理它们。将它们返回到解析器,就像对特殊字符一样。然后解析器可以处理它并通过丢弃来尝试恢复。

  3. 将此作为最终规则:

    . return yytext[0];
    

答案 1 :(得分:0)

我不确定这是否是最佳答案,但这对我有用。

%x ERROR
%%

{NL} {
    printf("New line.\n");
    return LINE_END;
}

<INITIAL,ERROR>{BLANK} {
    BEGIN(INITIAL);
}

{ID} {
    printf("ID recognized: '%s'\n", yytext);
    return ID;
}
<INITIAL,ERROR>. {
    fprintf(stderr, "ERROR: Invalid input in line %d: \"%s\"\n", yylineno, yytext);
    BEGIN(ERROR);
}

%%

阅读this以了解有关启动条件的更多信息。

(我试图解释我做过的事情) 每当此词法分析器遇到意外情况时,它就会专门激活两组规则。为了摆脱规则的错误集,词法分析者必须打一个“空白”。

答案 2 :(得分:0)

您可以使用此

假设您要识别保留字:

([\r\n\z]|" "|"")+"for"/([\r\n\z]|" ")+ {}
  • 任何新行字符或通常是控制字符[\r\n\z]
  • 或空格" "
  • 或行""
  • 的开头
  • 至少1次+
  • 引号"for"
  • 中您想要的单词
  • 仅后跟/
  • 几乎没有""至少1次的表达式 - &gt; ([\r\n\z]|" ")+

使用此代码,您可以为单词之前和之后需要做的事情形成自己的匹配模式。