因为是非计算机本科,所以没有学编译原理,进来想补补课,于是买了本《自制编程语言》,里面介绍了lex和yacc工具,于是装起来试了下。


原来用工具来解析字符串还是挺方便的,以前知道正则以后,就觉得这东西很好,现在有了lex和yacc,把正则能做的事情又放大了,能够做更丰富的事情。


例如,写一个简单的把字符串里的数字相加,其他忽略的程序(说是简单是指功能,其实调通很不简单,哈哈,特别是把%type写成了%token的笔误后,纠结了很久)


下面贴上代码

test.l

%{
#include <stdio.h>
#include "y.tab.h"
int
yywrap(void)
{ return 1; }
%}
%%
"\n"  return CR;
[0-9]+ {
    int temp;
    sscanf(yytext, "%d", &temp);
    yylval.int_value = temp;
    return A;
}
[ \t] ;
. {
		//other words
		yylval.int_value = 0;
    return ERR;
}
%%

test.y

%{
#include <stdio.h>
#include <stdlib.h>
%}
%union {
	int int_value;
}
%token <int_value> A B
%token CR ERR
//!!this is %type!!
%type <int_value> expression other
%%
line_list : line | line_list line;
line : expression CR {
	printf("%d\n", $1);
} | CR {
	printf("exit.\n");
	exit(0);
};
expression : A | other | expression A {
	$$ = $1 + $2;
} | expression other {
	$$ = $1 + $2;
};
other: ERR {
	printf(".");
};
%%
int
yyerror(char const *str) {
    extern char *yytext;
    fprintf(stderr, "parser error near %s\n", yytext);
    return 0;
}

int main(void) {
    extern int yyparse(void);
    extern FILE *yyin;

    yyin = stdin;
    if (yyparse()) {
        fprintf(stderr, "Error ! Error ! Error !\n");
        exit(1);
    }
}

然后利用lex和yacc来生成一个可执行文件

yacc -dv test.y
lex test.l
cc *.c

来看看执行效果吧

wKiom1YD5hLjBaNCAABCgAqCkjc437.jpg

嗯,还不错哦!