在flex / lex中实现单词边界状态(解析器生成器)

时间:2009-01-02 14:57:36

标签: parsing lex lexical-analysis

我希望能够预测模式匹配是否出现在单词字符之后或非单词字符之后。换句话说,我想在flex / lex不支持的模式开头模拟\ b word break regex char。

以下是我的尝试(无法按预期运行):

%{
#include <stdio.h>
%}

%x inword
%x nonword

%%
[a-zA-Z]    { BEGIN inword; yymore(); }
[^a-zA-Z]   { BEGIN nonword; yymore(); }

<inword>a { printf("'a' in word\n"); }
<nonword>a { printf("'a' not in word\n"); }

%%

输入:

a
ba
a

预期输出

'a' not in word
'a' in word
'a' not in word

实际输出:

a
'a' in word
'a' in word

我这样做是因为我想做the dialectizer这样的事情而且我一直想学习如何使用真正的词法分析器。有时我想要替换的模式需要是单词的片段,有时它们只需要是整个单词。

2 个答案:

答案 0 :(得分:2)

这就是我想要的成就:

%{
#include <stdio.h>
%}

WC      [A-Za-z']
NW      [^A-Za-z']

%start      INW NIW

{WC}  { BEGIN INW; REJECT; }
{NW}  { BEGIN NIW; REJECT; }

<INW>a { printf("'a' in word\n"); }
<NIW>a { printf("'a' not in word\n"); }

这样我可以在任何模式的开头或结尾处执行等效的\ B或\ b。您最后可以通过a/{WC}a/{NW}进行匹配。

我想设置状态而不消耗任何字符。诀窍是使用REJECT而不是yymore(),我想我并不完全理解。

答案 1 :(得分:1)

%%
[a-zA-Z]+a[a-zA-Z]* {printf("a in word: %s\n", yytext);}
a[a-zA-Z]+ {printf("a in word: %s\n", yytext);}
a {printf("a not in word\n");}
. ;

测试:

user@cody /tmp $ ./a.out <<EOF
> a
> ba
> ab
> a
> EOF
a not in word

a in word: ba

a in word: ab

a not in word