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

Parsing 灵活扫描,区分字符串(带单个空格)和填充(多个空格),parsing,bison,flex-lexer,Parsing,Bison,Flex Lexer,我在使用flex扫描看起来像这样的行时遇到了问题 DESCRIPTION This is the device description 我希望扫描该行,以便说明是一个标记,而“这是设备说明”是另一个标记 我一直在无休止地玩弄我的规则,但似乎无法让它发挥作用 从文档中,我想我想使用 `r/s' r,但仅当它后面跟s时 空间被接受的地方是,它们后面跟的不是一段时间的空间。我不知道如何用flex的语法编写这个规则。在我看来,规则应该是这样的 [a-zA-Z]("

我在使用flex扫描看起来像这样的行时遇到了问题

DESCRIPTION                    This is the device description
我希望扫描该行,以便说明是一个标记,而“这是设备说明”是另一个标记

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

从文档中,我想我想使用

`r/s' r,但仅当它后面跟s时

空间被接受的地方是,它们后面跟的不是一段时间的空间。我不知道如何用flex的语法编写这个规则。在我看来,规则应该是这样的

[a-zA-Z](" "/[a-zA-Z0-9]|[a-zA-Z0-9])*        return IDENTIFIER;
但这是无效的


我可以把每一个单词分成几行,但是我不能得到区分1个空格和1<空格的规则。Halp.

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

不管你怎么做,关键是弄清楚如何决定代币划分。考虑下面的四行,例如:

DEVICE      This is the device
MODE        This is the mode
DESCRIPTION This is the device description
UNDOCUMENTED FIELD
当然,第三行和第四行表示的角案例可能永远不会出现在任何输入中

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


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

我的意见是,您在这里使用了错误的马。lex(flex)只能用于词法分析,yacc(或bison)只能用于语法分析。如果说一个字符不是分隔符,但多个字符是分隔符,则不适用于lexer

我的意见是,lex应该只报告单词和填充,yacc应该在以后重新组合没有被填充元素分隔的单词

法律部分将非常简单:

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

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

此处省略操作,因为它们太依赖于您的实际处理。

这不是C编程语言问题,请删除“C”tag@user3629249:你和我一样有能力编辑问题;如果你想编辑它,你应该评论这个问题;不是我的答案。我不完全相信C标记是错误的,fwiw;如果我有更多的时间,我会建议使用C解决方案,而不是/以及由Flex生成的C解决方案。但这是你和海报之间的事…@rici,这对我来说是个新闻,我可以编辑一个OPs问题和相关标签。当然,这意味着我不知道如何编辑其他人的post@user3629249:问题/答案下面有一行小字,上面写着share/edit/delete/flag(或上面的某个子集)。但是,如果您只想更改标记,请使用web客户端,将鼠标悬停在标记上。无论如何,我不是mod(没有菱形!),所以你应该配合海报,而不是我:-)谢谢你的帮助。我可能对这个问题的处理方式很差。但我即将熟悉yacc,我相信一旦我熟悉了yacc,你的方法会更好。谢谢@谢尔盖巴列斯塔
[[:alpha:]]+( [[:alpha:]]+)*
[[:alnum:]_]+   {
        // printf("WORD: >%s<\n", yytext); // for debugging
        return WORD;
    }

[[:blank:]]{2,} {
        // printf("PADDING: >%s<\n", yytext);
        return PADDING;
    }
elt: PADDING
   | ident

ident: WORD
     | ident WORD