【问题标题】:Store matched characters in flex在 flex 中存储匹配的字符
【发布时间】:2017-05-28 01:32:39
【问题描述】:

我是新手,我想知道如何将匹配的字符存储在 Flex 程序中,然后将它们打印在 main 的一行中。我有以下模式和规则:

ID  [A]
ID1 [B]
ID2 [C]
ID3 [D]

%%
{ID}  
{ID1}  
{ID2}  
{ID3}  

【问题讨论】:

  • 这不是yytext 的用途吗?当然,就目前而言,您只有模式的默认操作(根据我的思维方式,ID 应该有一个数字后缀——但这是一个美学问题),所以您需要做一些工作给main() 一个处理匹配字符的机会。具有如图所示的单字母字符类有点奇怪,尽管在形式上并没有错。你也应该使用一些空间。
  • 是的,main 中有一个 yytext()
  • yytext()?一个函数?我习惯于认为yytextchar yytext[];char *yytext;,我似乎记得哪个变体可用取决于使用哪个Lex 变体,我不记得Flex 做了什么。您需要在每个模式之后添加一些内容以返回 main() — 类似 { return 1; } 的内容表示匹配成功。 IIRC,任何不匹配的内容都会被忽略。
  • 用户在给 ABCE 时检查了每个字符,当匹配完成后我想打印 ABCE 在主要部分匹配
  • 您误解了 Flex 的功能。您说过“一个令牌是 A;一个令牌是 B;一个令牌是 C;一个令牌是 D;一个令牌是 E”。如果您希望您的程序聚合所有这些,您必须安排这样做 - Flex 词法分析器中的标记化代码识别标记并安排在识别标记时执行您选择的代码(并且yytext 指向 (包含)最近匹配的标记——但只有最近匹配的标记;没有任何先前或后续标记)。

标签: c flex-lexer


【解决方案1】:

这或多或少是一个 MCVE (Minimal, Complete, Verifiable Example),用于识别和捕获部分工作——它还强制执行唯一性。它使用assert() 来确保标记是单个(非空)字符。

%{
#include <assert.h>
%}
%option noinput
%option nounput
%option noyywrap
ID0 [A]
ID1 [B]
ID2 [C]
ID3 [D]
ID4 [E]
%%
{ID0}       { printf("{ID0}: %s\n", yytext); return 1; }
{ID1}       { printf("{ID1}: %s\n", yytext); return 1; }
{ID2}       { printf("{ID2}: %s\n", yytext); return 1; }
{ID3}       { printf("{ID3}: %s\n", yytext); return 1; }
{ID4}       { printf("{ID4}: %s\n", yytext); return 1; }
.           { printf("  .  : %s\n", yytext);           }
%%

int main(void)
{
    char token[512] = "";
    char *ptr = token;

    /* Efficiency and safety is not under discussion */
    while (yylex())
    {
        assert(yytext[0] != '\0' && yytext[1] == '\0');
        if (strchr(token, yytext[0]) == 0)
            *ptr++ = yytext[0];
    }
    *ptr = '\0';
    printf("Token sequence: [%s]\n", token);
    return 0;
}

(我将ID 重命名为ID0,以使名称更加一致。)

示例运行(我使用名称 fx83.l 作为源代码,因此使用 fx83 作为从源代码生成的程序的名称):

$ ./fx83 <<< "aBcDeAbCdEFf"
  .  : a
{ID1}: B
  .  : c
{ID3}: D
  .  : e
{ID0}: A
  .  : b
{ID2}: C
  .  : d
{ID4}: E
  .  : F
{ID0}: A
{ID1}: B
  .  : d
{ID2}: C
{ID3}: D
  .  : e
{ID4}: E
{ID4}: E
  .  : f

Token sequence: [BDACE]
$

(我认为这并不重要,但我在 macOS Sierra 10.12.2 和 GCC 6.2.0 上使用 flex 2.5.35 Apple(flex-31)。)

【讨论】:

  • 非常感谢您的帮助和您的时间。现在可以了
猜你喜欢
  • 2021-11-27
  • 1970-01-01
  • 2016-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-30
  • 1970-01-01
相关资源
最近更新 更多