天天看點

使用Win-flex bison生成一個電腦(VS2022)

作者:alexabc3000

本文參考網頁“Flex和Bison簡介和Windows下使用入門”( ),使用Win-flex bison生成生成一個電腦(VS2022)。

1. 使用VS2022建立空項目

使用VS2022建立名為MyProject的空項目。項目所在目錄為“D:\temp\MyProject”。

2. 編寫lex及yacc(bison)程式(文本檔案)

2.1. lex程式

在目錄“D:\temp\MyProject”中,使用文本編輯器(比如Notepad++)建立名為“bo.l”文本檔案(即lex程式),内容如下:

%{

#include "b.y.h"

%}

%%

"+" {return ADD;}

"-" {return SUB;}

"*" {return MUL;}

"/" {return DIV;}

"|" {return ABS;}

[0-9]+ {yylval=atoi(yytext);return NUMBER;}

\n {return EOL;}

%%

int yywrap()

{

return(1);

}

2.2. yacc(bison)程式

在目錄“D:\temp\MyProject”中,使用文本編輯器(比如Notepad++)建立名為“b.y”文本檔案(即yacc程式),内容如下:

%{

#include <stdio.h>

%}

%token NUMBER

%token ADD SUB MUL DIV ABS

%token EOL

%%

calclist: /*空規則*/

|calclist exp EOL {printf("=%d\n",$2);};

exp:factor{$=$1;}

|exp ADD factor {$=$1+$3;}

|exp SUB factor{$=$1-$3;};

factor: term {$=$1;}

|factor MUL term{$=$1*$3;}

|factor DIV term{$=$1/$3;};

term:NUMBER {$=$1;}

|ABS term {$=$2>0?$2:-$2;};

%%

int main(int argc,char ** argv){

yyparse();

}

yyerror(char *s){

fprintf(stderr,"error:%s\n",s);

}

3. 使用flex和bison生成C語言程式

在指令行視窗輸入下列指令生成C語言程式(wincompat參數,指令lex編譯器建立Windows相容的程式):

path=D:\Programs\win_flex_bison-latest;%path%

cd D:\temp\MyProject

D:

win_bison --defines=b.y.h --output=b.y.c b.y

win_flex --wincompat --outfile=bo.yy.c bo.l

使用Win-flex bison生成一個電腦(VS2022)

我的win_flex程式所在目錄為“D:\Programs\win_flex_bison-latest”。

使用Win-flex bison生成一個電腦(VS2022)

上述指令正常執行後,生成檔案“bo.yy.c”、“b.y.h”、“b.y.c”。

經上述步驟之後,目錄“D:\temp\MyProject”中的内容如下圖所示:

使用Win-flex bison生成一個電腦(VS2022)

4. 在VS2022編譯程式

在VS2022的中(即項目的“解決方案資料總管”視圖),将“bo.yy.c”、“b.y.h”、“b.y.c”添加到上文建立的空項目MyProject中。

使用Win-flex bison生成一個電腦(VS2022)

編譯程式即可運作。

為了達到更好的調試效果,需要将預編譯指令“#line”注釋掉,因為使用預編譯指令“#line”時,調試時會到其使用的檔案中(為了提高效率,可以使用替換視窗将字元串“#line”替換為“//#line”)

運作效果如下:

使用Win-flex bison生成一個電腦(VS2022)

5. 程式的改進

上述步驟生成的程式隻能進行整數的加減乘除運算,不能進行浮點數的預算,為了進行浮點數的運算,可做如下修改。

(1)lex程式“bo.l”文本檔案的修改。将

[0-9]+ {yylval=atoi(yytext);return NUMBER;}

改為

[0-9]+(.[0-9]+)? {yylval=atof(yytext);return NUMBER;}

(2)yacc程式“b.y”文本檔案的修改。将

|calclist exp EOL {printf("=%d\n",$2);};

改為

|calclist exp EOL {printf("=%3.3lf\n",$2);};

(3)使用win_bison和win_flex生成檔案“bo.yy.c”、“b.y.h”、“b.y.c”。

(4)頭檔案“b.y.h”的修改。将

typedef int YYSTYPE;

改為

typedef double YYSTYPE;

(5)檔案“b.y.c”的修改。将

typedef int YYSTYPE;

改為

typedef double YYSTYPE;

(5)在VS2022中重新編譯生成項目。

運作效果如下圖所示:

使用Win-flex bison生成一個電腦(VS2022)

1. 若幹錯誤的解決方法

1.1. error C4996

error C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

錯誤解決方法可參看網頁:

在項目屬性對話框的預處理器中添加“_CRT_SECURE_NO_WARNINGS”。

使用Win-flex bison生成一個電腦(VS2022)