我正在写一个词法分析器,我正在使用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.
答案 0 :(得分:1)
你似乎一次要问两个问题。
'整字'不是编程语言中公认的结构。词法和语法已经定义。只需实施它们。
在flex中处理非法或意外字符的最佳方法是根本不处理它们。将它们返回到解析器,就像对特殊字符一样。然后解析器可以处理它并通过丢弃来尝试恢复。
将此作为最终规则:
. 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]
" "
""
+
"for"
/
""
至少1次的表达式 - &gt; ([\r\n\z]|" ")+
使用此代码,您可以为单词之前和之后需要做的事情形成自己的匹配模式。