上篇介绍了c的yacc计算器程序, 那不行,c++有那么多库,stl什么的,能用c++更好,好开始动手。
首先我将原先生成的*.c都改成了*.cpp,编译,发现报如下错:
(本来我是把报错信息都copy下来的,无奈写到一半IE崩溃,我没保存,泪)
大致是 unistd.h 没找到。
这个查了一下,可以如下解决,找到vs2008的vc include目录,在文件夹下创建个unistd.h文件,输入如下内容:
#if _MSC_VER > 1000
#pragma once
#endif
#ifndef _INC_UNISTD
#define _INC_UNISTD
#include <io.h>
#include <process.h>
#endif
然后再编译,就不存在此问题了,这是编译报yywrap等得错,这个一看应该明白,是由于c++编译时会将函数编译为一个只有编译器认识的函数,(c++为了实现虚函数),那么因为yywrap等类似的函数实际是c的代码, 那么我们要强制告诉c++,这些个函数给我留着,就叫这名,于是extern "C"配上用场了。话不多说了,上代码
frame.l
%{
#include <string>
#include "frame.tab.h"
extern "C" {
int yywrap(void);
void yyerror(char *);
}
%}
%%
[a-z] {yylval=*yytext-'a'; return VARIABLE; }
[0-9]+ { yylval=atoi(yytext); return NUMBER;}
[-+=()/*\n] {return *yytext;}
[\t ]
. {yyerror("invalid char\n");}
%%
int yywrap(void)
{
return 1;
}
frame.y
%{#include <iostream>
extern "C" {
void yyerror(const char *s);
}
extern FILE *yyin;
int yylex(void);
int sym[26];
%}
%token NUMBER VARIABLE
%%
program:
| program statment '\n';
statment: expr { std::cout<<"expr="<<$1<<std::endl;}
|VARIABLE'='expr { sym[$1]=$3; std::cout<< sym[$1];}
;
expr:expr '+' term {$$=$1+$3; }
|expr '-' term {$$=$1-$3;}
|term {$$=$1;}
;
term:
term '*' factor {$$=$1*$3; }
|term '/' factor {$$=$1/$3;}
|factor {$$=$1;}
;
factor:
NUMBER {$$=$1;}
| '(' expr ')' {$$=$2;}
|VARIABLE {$$=sym[$1];}
;
%%
void yyerror(const char *s)
{
printf("err:%s\n",s);
}
int main()
{
do{
yyparse();
}while(!feof(yyin));
return 0;
}
顺便说几句,要特别注意frame.l 中 %% 和下面[a-z] 这中间不能有除了回车外其他的空格,否则会出错,莫名其妙的。