在 flex 中存储匹配的字符

Store matched characters in flex

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

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

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

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

%{
#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] != '[=10=]' && yytext[1] == '[=10=]');
        if (strchr(token, yytext[0]) == 0)
            *ptr++ = yytext[0];
    }
    *ptr = '[=10=]';
    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]
$

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