加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

创建一门新的编程语言-Flex&Bison教程-(2)-加减乘除

发布时间:2020-12-15 04:01:22 所属栏目:百科 来源:网络整理
导读:上一篇基本介绍了一些知识,那么现在我们就尝试做一个简单的计算器 首先先写bison文件 test2yy.y %{ #include iostream using namespace std; int yylex(); //只是一个声明 int yyerror(const char *); //必须要有%}%token dv Number%type dv exp%union { do

上一篇基本介绍了一些知识,那么现在我们就尝试做一个简单的计算器

首先先写bison文件

test2yy.y

%{
  #include <iostream>
  using namespace std;
  int yylex();  //只是一个声明
  int yyerror(const char *); //必须要有
%}
%token <dv> Number
%type <dv> exp
%union {
  double dv;
}
%left '+' '-'
%left '*' '/'
%%

main : main exp 'n' { cout << "Result : " << $2 << endl; }
     | 
     ;

exp  : exp '+' exp  { $$ = $1 + $3 }
     | exp '-' exp  { $$ = $1 - $3 }
     | exp '*' exp  { $$ = $1 * $3 }
     | exp '/' exp  { $$ = $1 / $3 }
     | '(' exp ')'  { $$ = $2 }
     | Number       { $$ = $1 }
     ;
  
%%

int yyerror(const char *emseg)
{
	cout << "Error: " << emseg << endl;
}

int main()
{
  yyparse();
}


在这里我们需要关注一些事情

bison默认第一个表达式(文中的main)为默认表达式,意思是程序执行时处理的表达式,而其他的(文中的exp)则作为辅助,所以你不必一定要命名它为main

%left的作用是规定左优先,因为加减乘除中的乘除需要先运算,在有多个%left的情况下,越下优先级越高

什么意思?假如有

....
%left 'a' 'b'
%left 'c'
%left 'd'
....
那么当遇到这串东西的时候:

a c b d

首先d被处理,然后是c,a和b优先级相同,按先后处理

那么,既然有左优先,那就肯定还有右优先

%right

右优先怎么用呢?看这两个例子:

5+2*4-1/3

a = b = c = d

上面的是一个算式,算式是要从左到右算的,因此是左优先

下面是一个赋值语句,需要从右边赋值到左边,那么我们就可以

%right '='


继续看,我们又发现了$$这个新变量,它代表的是当前表达式的值,所以我们要告诉bison这个表达式的类型是什么,于是便有了上面的%type <dv> exp

实际上

%token <dv> Number

%token Number

%type <dv> Number

等价


好了,让我们来看新的flex文件

test2ll.l

%{
  #include <iostream>
  #include "test2yy.h"  //由bison生成
  extern int yyerror(const char *);
  using namespace std;
%}
%%
[0-9]+         { yylval.dv = strtod(yytext,0); return Number; }  //无小数点
[0-9]+.[0-9]+ { yylval.dv = strtod(yytext,0); return Number; }  //有小数点
[)(+*-/n]       { return *yytext; } //直接返回字符为符号
[ t]          ; //忽略空格         
%%
int yywrap()
{
  return 1;
}

这里和上一篇比没有什么差别,就不说了


bison -d -otest2yy.c test2yy.y
flex -otest2ll.c test2ll.l
g++ test2*.c -otest2
./test2

随便输入点算式,是不是成功了?


(2)-加减乘除 结束

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读