灵活扫描,区分字符串(单个空格)和填充(多个空格)

时间:2017-11-30 16:39:00

标签: parsing bison flex-lexer

我无法使用flex来扫描看起来像这样的行

DESCRIPTION                    This is the device description

我希望对该行进行扫描,以便 DESCRIPTION 是一个令牌" 这是设备说明"是另一个。

我一直在无休止地玩我的规则,但似乎无法让它发挥作用。

从文档中我想我想用

实现规则
  

`R / S'   一个r,但只有它后面跟着一个s

只接受空格的是它们之后是不是空格的东西。我不知道如何用flex的语法编写这个规则。在我看来,规则应该是

[a-zA-Z](" "/[a-zA-Z0-9]|[a-zA-Z0-9])*        return IDENTIFIER;

但这是无效的。

我可以得到用来切断每个单词的行,但是我无法得到区分1个空格和1个单词的规则。空间。 HALP。

2 个答案:

答案 0 :(得分:1)

这对于flex来说并不是一个很好的匹配,因为令牌的识别是依赖于上下文的。您可以使用start conditions实现与上下文相关的扫描,但过度使用启动条件通常表明其他一些扫描机制会更好。

无论你如何做,关键是要弄清完全如何决定令牌分裂。请考虑以下四行,例如:

DEVICE      This is the device
MODE        This is the mode
DESCRIPTION This is the device description
UNDOCUMENTED FIELD

当然,第三行和第四行代表的角落案例可能永远不会出现在您的任何输入中。

如果第一个令牌不能包含空格,那么问题相对简单,虽然你仍然需要一个开始条件(我假设你已经阅读了上面链接的文档):

%x WHITE WORDS
%%
  /* Possibly should be [[:alpha:]] instead of [[:upper:]] */
[[:upper:]]+   { /* copy yytext */; BEGIN(WHITE); return KEYWORD; }
  /* Handle other possible line beginnings */
<WHITE>\n      { /* Blank descriptive text */; BEGIN(INITIAL); }
<WHITE>[ \t]+  { BEGIN(WORDS); }
<WHITE>.       { /* Something not correct in this line */; ... }
<WORDS>.+      { /* copy yytext */; BEGIN(INITIAL); return DESCRIPTION; }
<WORDS>\n      { BEGIN(INITIAL); }

如果第一个标记中可能有空格但行中不能有两个空格,则可以将上面的第一个模式替换为:

[[:alpha:]]+( [[:alpha:]]+)*

将匹配任何单词序列(仅由字母组成),其中连续单词之间只有一个空格。与上面的原始模式一样,这将以找到的第一个非字母字符结束。该错误将由<WHITE>中的规则检测到,因为当启动条件变为活动状态时遇到的任何非空白字符将由启动条件的默认规则(<WHITE>.规则)处理。

答案 1 :(得分:0)

我的意见是你在这里使用了错误的马。 lex(flex)应仅用于词法分析和yacc(或bison)用于句法分析。假设一个单个字符不是分隔符而是多个字符不适合词法分析器。

我的观点是,lex应该只报告单词和填充,并且yacc稍后应该重新组合未被填充元素分隔的单词。

lex部分简单如下:

|x-y|=0

并且yacc部分将包含:

[[:alnum:]_]+   {
        // printf("WORD: >%s<\n", yytext); // for debugging
        return WORD;
    }

[[:blank:]]{2,} {
        // printf("PADDING: >%s<\n", yytext);
        return PADDING;
    }
这里省略了

动作,因为它们过分依赖于您的实际处理。