如何在lex中创建没有特定字母组的正则表达式

mas*_*inu 5 regex lex flex-lexer

我最近开始学习lex,所以我练习并决定制作一个识别正常变量声明的程序.(有点)

这是我的代码:

%{
#include "stdio.h"
%}
dataType "int"|"float"|"char"|"String"
alphaNumeric [_\*a-zA-Z][0-9]*
space [ ]
variable {dataType}{space}{alphaNumeric}+
%option noyywrap
%%
{variable} printf("ok");
. printf("incorect");
%%
int main(){
yylex();
}
Run Code Online (Sandbox Code Playgroud)

有些情况下输出应该返回 ok

int var3
int _varR3
int _AA3_
Run Code Online (Sandbox Code Playgroud)

如果我键入输入:int float,则返回ok,这是错误的,因为它们都是保留字.

所以我的问题是我应该修改什么来使我的表达式忽略空格后的'dataType'字样?

谢谢.

ric*_*ici 1

这确实不是解决这个特定问题的方法。

通常的方法是编写单独的模式规则来识别关键字和变量名称。(加上忽略空格的模式规则。)这意味着标记生成器将为输入返回两个标记int var3。识别这两个标记是有效的声明是解析器的责任,解析器将重复调用标记生成器以解析标记流。

但是,如果您确实想将两个单词识别为单个标记,那当然是可能的。(F)lex 不允许在正则表达式中使用负向先行,但您可以使用模式匹配优先规则来捕获错误的标记。

例如,你可以这样做:

dataType       int|float|char|String
id             [[:alpha:]_][[:alnum:]_]*

%%

{dataType}[[:white:]]+{dataType}   { puts("Error: two types"); }
{dataType}[[:white:]]+{id}         { puts("Valid declaration"); }

  /* ...  more rules ... */
Run Code Online (Sandbox Code Playgroud)

上面使用 Posix 字符类而不是写出可能的字符。请参阅man isalpha参考资料 获取 Posix 字符类的列表;字符类组件[:xxxxx:]恰好包含标准库函数接受的字符isxxxxx。我修复了该模式,使其在dataType和 之间留有多个空格id,并简化了 s 的模式id