阅读《自制编程语言》之使用flex&bison和c语言制作一个简易计算器

 

写在前面:这本书相当于给没有什么编译原理基础又想要做一个玩具的程序猿做的一个很浅的科普。但它确确实实能走一遍流程。

 

 

   昨天翻了翻《龙书》,实在受不了,对菜逼太不友好了。网上一搜,有人推荐这本书。好在手头有这个玩意儿,都快蒙灰了,就拉出来看看,简直感动要哭,真的是一步一步喂到嘴里,最重要的是它简单哈哈。话不多说,上教程。
 
准备工作 :linux
 
在windows当中安装虚拟机然后下载linux镜像的教程:

https://jingyan.baidu.com/article/c275f6ba07e269e33d756714.html

 

 

借用一下百度经验里面的。

 

 

ubuntu16.04下载地址 : http://cn.ubuntu.com/download/
 
两个命令 sudo apt install flex
                sudo apt install bison
完成 flex和bison的安装后就可以开始写啦。

 

1、词法分析。
词法分析就是把一堆字符分析成为有意义的单词。对于四则计算器有单词就是数值以及加减乘除换行符的符号了。所以词法分析要做的事情就是把用户输入的词,选择有意义分析出来。

 

 

 

于是新建 mycalc.c文件

 

 
%{
 #include<stdio.h>
 #include"y.tab.h"
 int yywrap(void)
 {
  return 1;
 }
%}
%%
"+"                                   return ADD;
"-"                                    return SUB;
"*"                                    return MUL;
"/"                                    return DIV;
"\n"                                  return CR;
([1-9][0-9]*)|0|([0-9]+\.[0-9]+) {
  double temp;
  sscanf(yytext,"%lf",&temp);
  yylval.double_value =  temp;
  return DOUBLE_LITERAL;
}
[ \t];
. {
 fprintf(stderr,"lexical error.\n");
 exit(1);
}
%%

————————————————————————我是分界线——————————————

 

 

%{
 #include<stdio.h>
 #include"y.tab.h"
 int yywrap(void)
 {
  return 1;
 }
%}
词法分析器将会把这部分代码原模原样输出。
%%
"+"                                   return ADD;
"-"                                    return SUB;
"*"                                    return MUL;
"/"                                    return DIV;
"\n"                                  return CR;
([1-9][0-9]*)|0|([0-9]+\.[0-9]+) {
  double temp;
  sscanf(yytext,"%lf",&temp);
  yylval.double_value =  temp;
  return DOUBLE_LITERAL;
}
[ \t];
. {
 fprintf(stderr,"lexical error.\n");
 exit(1);
}
%%
筛选加减乘除反斜杠换行符以及使用正则表达式筛选整数和小数

 

 

 
2、语法分析
既然单词分析完了,就应该把单词连成有意义的短句
%{
 
#include<stdio.h>
 
#include<stdlib.h>
 
#define YYDEBUG 1
 
%}
 
 
 
%union {           /* 声明非终结符种类 */
 
 int           int_value;
 
 double  double_value;
 
}
 
%token <double_value>   DOUBLE_LITERAL
 
%token ADD SUB MUL DIV CR
 
%type <double_value> expression term primary_expression                 /* 非终结符有这些 */
 
%%
 
line_list     /* 多行的规则 */
 
 : line
 
 | line_list line
 
 ;
 
line                    /* 单行*/
 
 : expression CR
 
 {
 
  printf(">>%lf\n",$1);
 
 }
 
expression  /* 表达式*/
 
 : term
 
 | expression ADD term
 
 {
 
  $$=$1 + $3;
 
 }
 
 | expression SUB term
 
 {
 
  $$=$1 - $3;
 
 }
 
 ;
 
term   /* 和项的规则 */
 
 : primary_expression
 
 | term MUL primary_expression
 
 {
 
  $$=$1 * $3;
 
 }
 
 | term DIV primary_expression
 
 {
 
  $$=$1 / $3;
 
 }
 
 ;
 
primary_expression  /* 一元表达式 */
 
 : DOUBLE_LITERAL
 
 ;
 
%%
 
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);
 
 }
 
}

 

————————————————————————我是分界线——————————————

 

执行命令

 

 

20180209213734470
 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值