莱克斯/柔性
69 个字符。在此处的文本中,我将制表符更改为 8 个空格,以便看起来正确,但所有这些连续的空格都应该是制表符,并且制表符很重要,所以它出现了 69 个字符。
#include <stdio.h>
%%
HAA|HH|H printf("AH");
AAH|AA|A printf("HA");
对于它的价值,生成lex.yy.c
的是 42736 个字符,但我认为这并不重要。我可以(并且很快会)编写一个更短的纯 C 版本并且做同样的事情,但我觉得这可能应该是一个单独的条目。
编辑:
这是一个更合法的 Lex/Flex 条目(302 个字符):
char*c,*t;
#define s(a) t=c?realloc(c,strlen(c)+3):calloc(3,1);if(t)c=t,strcat(c,#a);
%%
free(c);c=NULL;
HAA|HH|H s(AH)
AAH|AA|A s(HA)
%%
int main(void){c=calloc(2,1);if(!c)return 1;*c='H';for(int n=0;n<10;n++)printf("n = %d | %s\n",n,c),yy_scan_string(c),yylex();return 0;}int yywrap(){return 1;}
这会进行多次迭代(与上一次迭代不同,它只进行一次迭代,每次都必须手动播种,但产生了正确的结果),并且具有看起来非常可怕的代码的优势。我使用一个函数宏、字符串化运算符和两个全局变量。如果您想要一个甚至不检查malloc()
失败的更混乱的版本,它看起来像这样(282 个字符):
char*c,*t;
#define s(a) t=c?realloc(c,strlen(c)+3):calloc(3,1);c=t;strcat(c,#a);
%%
free(c);c=NULL;
HAA|HH|H s(AH)
AAH|AA|A s(HA)
%%
int main(void){c=calloc(2,1);*c='H';for(int n=0;n<10;n++)printf("n = %d | %s\n",n,c),yy_scan_string(c),yylex();return 0;}int yywrap(){return 1;}
一个更糟糕的版本可能是在堆栈上的哪里c
是数组,我们只是给它MAX_BUFFER_SIZE
某种形式,但我觉得这太过分了。
...只是在开玩笑。207 个字符,如果我们采取“99 个字符就足够了”的心态:
char c[99]="H";
%%
c[0]=0;
HAA|HH|H strcat(c, "AH");
AAH|AA|A strcat(c, "HA");
%%
int main(void){for(int n=0;n<10;n++)printf("n = %d | %s\n",n,c),yy_scan_string(c),yylex();return 0;}int yywrap(){return 1;}
我偏爱效果最好的那个(即第一个可以迭代直到内存耗尽并检查其错误的那个),但这是代码高尔夫。
要编译第一个,请键入:
flex golf.l
gcc -ll lex.yy.c
(如果你有lex
而不是flex
,只需更改flex
为lex
。它们应该是兼容的。)
要编译其他的,请键入:
flex golf.l
gcc -std=c99 lex.yy.c
否则 GCC 会抱怨‘for’ loop initial declaration used outside C99 mode
和其他废话。
纯C答案即将出现。