FLEX 用日期替换单词

FLEX replace words with dates

我对 flex 真的很陌生,遗憾的是,与其他语言相比,互联网上的例子很少。 我要替换的话:

  1. TODAY 是今天的日期
  2. TOMORROW 明天日期 1
  3. YESTERDAY 是昨天的日期
  4. TODAY-n,今天是 n 天之前的日期
  5. TODAY+n 是 n 天后的今天。

我做了一些研究,我唯一发现的就是用字符串中的另一个词替换 1 个词。这是完全不同的。

我取得了一些进展:

TODAY "TODAY"
YESTERDAY "YESTERDAY"
TOMORROW "TOMORROW"
TODAY+n "TODAY+n"
TODAY-n "TODAY-n"

%%
{TODAY} {op=1;}
{YESTERDAY} {op=2;}
{TOMORROW} {op=3;}
{TODAY+n} {op=4;}
{TODAY-n} {op=5;}
%%

date()
{
    if (op==0)
    
    a=(yytext);
    
    switch(op)
    {
        case 1:TODAY;
        break;
        
        case 2:YESTERDAY;
        break;
        
        case 3:TOMORROW;
        break;
        
        case 4;TODAY+n;
        break;
        
        case 5;TODAY-n;
        break;
    }
    op=0;
}

这是一个非常基本的实现,专注于 flex 而不是计算和显示日期的复杂性。这取决于以下事实:无法识别的字符的默认操作是将它们复制到输出流。但是,为了避免识别单词中间的 TODAY(如 AATODAYBB),我添加了一个模式来匹配任何仅包含字母字符的单词并将其显式复制到输出流(使用 ECHO).根据您的实际需要,您可能需要对其进行调整。

快速阅读 flex manual 应该足以理解该程序。尤其要看一下介绍性的material,包括简单的例子;模式的描述(与标准正则表达式相似但不完全相同,但缺少许多昂贵的功能,如捕获);以及扫描输入方式的描述。最后一节还解释了所谓的“最大 munch”(第一个最长匹配)算法,它在最后一个规则(必须是最后一个规则)中使用。

%option noinput nounput noyywrap
%{
    #include <stdio.h>
    #include <string.h>

    /* Replace this with a function which actually shows the correct date */
    void show_date(int offset) {
      if (offset > 0)
        fprintf(yyout, "<today's date + %d>", offset);
      else
        fprintf(yyout, "<today's date %.0d>", offset);
    }
%}

%%
TODAY           { show_date(0); }
TOMORROW        { show_date(1); }
YESTERDAY       { show_date(-1); }
TODAY[+-][0-9]+ { show_date(atoi(yytext + 5)); /* +5 to skip TODAY */ }
[[:alpha:]]+    { ECHO; /* Avoid false matches. See text. */ }

编译和运行:

# (Assuming the above file is called date_subst.l)
flex -o date_subst.c date_subst.l
gcc -Wall -g -o date_subst date_subst.c -lfl
./date_subst