windows 下写yacc程序的经典计算器例子

本文介绍了如何在Windows下使用Yacc构建经典计算器程序。通过在Visual Studio 2008中配置预处理事件,结合Vim编辑器进行源文件编辑,并利用bison生成C++代码。详细步骤包括编辑.y和.l文件,设置预处理事件,最后在VS2008中编译运行。
摘要由CSDN通过智能技术生成

      最近在单位的几个小模块中,大胆加入了antlr,使原本呆板的功能增色不少,于是便蠢蠢欲动,想着用用yacc,后续为公司现在搞的胖客户端瘦瘦身。这是后话了。

      且说在琢磨Yacc的时候,还是遇到不少问题,首先,我一般不写c++,c程序,所以不像好多人直接在linux下,用vi写代码,也不似很多人在win下,就用个ultraedit,当然这两个工具都挺好用,比如ultraedit有个列模式,那个功能真不错,和在linux下使用awk有些类似,跑题了,我是说我还是钟爱IDE,喜欢vs2008+红苹果的那种感觉,不喜欢记那么多的函数,只需要大概记得一些即可,所以我一开始的目标是在vs2008下使用生成的代码。所以在google上搜vs2008 yacc,的确出来不少,其中一个是parse generator2的软件,我也下了下,也按照文章中说的方法,在vs2008下重新编译了一下,确实也不错,可以用yacc生成出c++,c,java代码来。这个后续再慢慢研究了。现在我说的一种比较简单的方法,在vi上面编辑*.l,*.y,然后调用命令生成.c文件,在2008下编译。

       首先我转载一下,博客园的一片文章:

        http://www.cnblogs.com/P_Chou/archive/2010/03/24/1693763.html

       这篇文章已经说的较为详细了,如何配置,但我这里增加一点,在vs2008里编辑*.l,*.y没有语法着色功能,这个对我而言不太好,于是,我决定用vim来进行编辑,当然也可以直接在vim中调用bison 等命令来生成代码。 还是用原博文中推荐的方法吧,不过我略改了下,将预生成事件的命令做了一点改动,就免得每次拷贝那连个simple和hairy文件了。一切都准备好,我就摩拳擦掌于那个《编译原理与实践》里一开始就讲的计算器程序了。

       实际上书上第5章已经有相应的yacc的例子了,但它那个是一个只写了.y文件的,我这边来一个 .l+.y的。贴代码:

这个是frame.l    ,其中  \n {return 0;} 较为重要,可以去掉直接写为 \n 试试。             

%{
#include "frame.tab.h"
        int yywrap(void);

        %}

        %%
        [0-9]+ { yylval=atoi(yytext);  return NUMBER;}
        [\t ]
        \+ { return PLUS;}
        - {return MINUS;}
        \* {return MUL;}
        \/  {return DIV;}
        \( {return LP;}
                        \) {return RP;}
        \n {return 0;}
        %%

int yywrap(void)

{        

        return 1;

}

 

frame.y文件


 

%{
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
        void yyerror(const char *s);
        extern FILE *yyin;
%}

        %token NUMBER PLUS MINUS LP RP MUL DIV

%%

        program:  expr  { printf("expr:%d\n",$1);};
expr:expr PLUS term {$$=$1+$3; }
|expr MINUS term {$$=$1-$3;}
|term {$$=$1;}

;


term:term MUL factor {$$=$1*$3; }
|term DIV factor {$$=$1/$3;}
|factor {$$=$1;}
;
factor: NUMBER {$$=$1;}
| LP expr RP {$$=$2;}

%%

void yyerror(const char *s)
{

        printf("err:%s\n",s);
}

int main()

{        
        do{
                yyparse();        
        }while(!feof(yyin));
        return 0;

} 

然后在vs2008中建个工程,按照上面链接中博客园文章中说的,建立工程,将frame.l,frame.y分别加入,加入预处理事件,点击重新生成,然后将.h,.c文件都加入工程,F5编译即可。

下面是运行图片:

好的,这是一个关于用lex和yacc写的计算器的问题。使用lex和yacc可以轻松地创建一个简单的计算器,可以处理基本的数学运算,例如加减乘除,也可以支持括号和变量。 在使用lex和yacc创建计算器时,可以使用lex生成一个词法分析器来分析输入的字符串,yacc则可以生成一个语法分析器来将输入的字符串转换为可执行代码。在编写代码时,需要使用lex和yacc的规则来定义词法和语法分析器的行为。 例如,下面是一个使用lex和yacc编写的计算器例子: 首先,使用lex创建一个词法分析器,用于将输入的字符串分解成单个令牌: ``` %{ #include "y.tab.h" %} %% [0-9]+ { yylval = atoi(yytext); return NUMBER; } [+\-*/()=] { return yytext[0]; } [a-zA-Z][a-zA-Z0-9]* { yylval = yytext[0]; return VARIABLE; } [ \t\n] { /* ignore whitespace */ } . { printf("Unknown token %s\n", yytext); } %% int yywrap() { return 1; } ``` 上面的代码定义了识别数字、加减乘除、括号、变量等令牌的规则。注意,这里使用了y.tab.h头文件,这是由yacc自动生成的头文件,包含了从语法分析器返回的令牌类型。 接下来,使用yacc创建一个语法分析器,用于将输入的令牌转换为可执行代码: ``` %{ #include <stdio.h> #include <stdlib.h> %} %token NUMBER VARIABLE %left '+' '-' %left '*' '/' %% statement: expression '\n' { printf("Result: %d\n", $1); } | VARIABLE '=' expression '\n' { printf("Variable %c set to %d\n", $1, $3); } ; expression: NUMBER { $$ = $1; } | VARIABLE { $$ = variables[$1 - 'a']; } | expression '+' expression { $$ = $1 + $3; } | expression '-' expression { $$ = $1 - $3; } | expression '*' expression { $$ = $1 * $3; } | expression '/' expression { $$ = $1 / $3; } | '(' expression ')' { $$ = $2; } ; %% ``` 上面的代码定义了语法规则,包括基本的数学运算、括号、变量等功能。 最后,可以将上述代码编译成可执行文件并运行,就可以使用自己编写的计算器了。 总之,使用lex和yacc创建计算器是一个非常有趣的项目,可以让你深入了解编译原理和语法分析器的实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值