在flex

时间:2017-01-12 19:47:38

标签: c flex-lexer

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

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

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

1 个答案:

答案 0 :(得分:0)

这或多或少是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)。)