Redy语法分析--一个简单的四则运算计算器
来源:互联网 发布:天宫一号 知乎 编辑:程序博客网 时间:2024/05/30 05:09
返回文档首页
(一)简介
代码下载: git clone git://git.code.sf.net/p/redy/code redy-code
这一章的内容:
使用yacc实现一个简单的四则运算计算器
(二)四则运算计算器
这一章里面我会讲解怎么使用yacc来完成一个简单的四则运算器,该计算器功能有:
- 有26个寄存器,分别用'a'-'z'来表示,用来保存数据,以便后面使用
- 支持加法,减法,乘法, 除法这四种运算
- 支持括号
- 不持浮点数的运算,当除法运算结果不为整数时,舍弃小数部份。
- 当输入是错误表达式时,输出为“Syntax Error",否则输出运算的结果
使用方法为:
- 字母=表达式 表示把表达式的值保存寄存器中。例如:a=1+3 ,运行后,寄存器a的值为4
- 运算单元可以是整数,也可以是寄存器,例如1*3+2, a+b+3*c。
(1)文法分析
四则运算合运算符的优先级为:
- 括号,运算单元(整数,寄存器)
- 一元运算符'-',表示负数
- 乘号和除号这两个运算符
- 加号和减号
- 等号,用于把结果保存到寄存器中
在写文法这前,先介绍一下yacc的书写格式
- 符号’:'左边为产生式左部,右边为产生式右部,右部的多个文法符号用空格分开。
- 如果左部的文法符号可以推导出多个字符串情况,用'|'把它们分开。
- 在每个产式的右部,可以嵌入语义动作,放在大括号中,$$表示产生式左部文法符号的属性,$i表示产生式右部第i个文法的属性。
- 如果在程序中没有嵌入语义动作,yacc则采用缺省语义动作。
编写文法的算述表达式文法的技巧为,先运算符的优先级是高的,接着依次到最底第一步,这里面括号,运算单元(整数,寄存器)的化先级最高,文法为:
primary_expr: '(' expr ')' {$$=$2;}| number| letter {$$=reg[$1];};
其中:
- 第一行语义动作表示,把第二个文法符号的属性(即expr)的值,赋值给产生式左部的文法符号primary_expr
- 第三行语义动作表示,把letter所表示寄存器中的值取出,赋值给primary_expr。
- 第二行采用是缺省的语义动作,为$$=$1,表示把number的值赋给primary_expr
第二步,为优先级第二运算符编写文法:
unary_expr: primary_expr | '-' primary_expr {$$=-$2;} ;第三步,接着为乘号和除号:
mul_expr:unary_expr {$$=$1;}| mul_expr '*' unary_expr {$$=$1*$3;}| mul_expr '/' unary_expr {$$=$1/$3;};
第四步,为加号和减号:
add_expr:mul_expr {$$=$1;}| add_expr '+' mul_expr {$$=$1+$3;}| add_expr '-' mul_expr {$$=$1-$3;};
最后为:
assign: letter '=' add_expr {reg[$1]=$3;};
到现在为些已经完成了算术表达式的编写,下面我给出整个源程序
%{#include<stdio.h>#include<ctype.h>int reg[26];%}%start list%token digit letter%%list: list start '\n' | list error '\n' | start '\n';start: expr {printf("result: %d\n\n",$1);}| assign;number:number digit {$$=$1*10+$2;} |digit ;primary_expr: '(' expr ')' {$$=$2;}| number| letter {$$=reg[$1];};unary_expr: primary_expr | '-' primary_expr {$$=-$2;} ;mul_expr:unary_expr {$$=$1;}| mul_expr '*' unary_expr {$$=$1*$3;}| mul_expr '/' unary_expr {$$=$1/$3;};add_expr:mul_expr {$$=$1;}| add_expr '+' mul_expr {$$=$1+$3;}| add_expr '-' mul_expr {$$=$1-$3;};assign: letter '=' add_expr {reg[$1]=$3;};expr: add_expr ;%%int yylex(){int ch=' ';while(isspace(ch)&&ch!='\n') ch=fgetc(stdin);if(isdigit(ch)){yylval=ch-'0';return digit;}if(isalpha(ch)){yylval=ch-'a';return letter;}return ch;}int main(){return yyparse();}int yyerror(char* s){fprintf(stderr,"%s\n",s);}
运行结果
这一章的代码可以在tutorial/syntax/simple_cal中找到
返回文档首页
- Redy语法分析--一个简单的四则运算计算器
- Redy语法分析--简介
- Redy语法分析--语法分析工具yacc
- 一个简单的四则运算计算器
- Redy语法分析--抽象语法树的数据结构
- Redy语法分析--文字常量结点
- Redy语法分析--一元运算符(+ - ~)
- Redy语法分析--算术运算符(* /. % + - )
- Redy语法分析--位运算符(<< >> & ^ | )
- 简单的四则运算计算器
- 简单的四则运算计算器
- Redy语法分析--抽象语法树简介
- Redy语法分析--抽象语法树简介
- Redy语法分析--语句与复合语句结点
- 学习C++的成果,一个简单的四则运算计算器内核
- 简单的web四则运算计算器
- 一个四则运算的小小计算器
- 对于c++来说,最简单的就是四则运算了,这里有一个四则运算的计算器
- linux iostat 命令详解!
- WIZNet官方博客开通啦!
- Linux常用的几个监控系统性能的命令
- MFC--小知识总结二
- The current identity (NT AUTHORITY/NETWORK SERVICE)
- Redy语法分析--一个简单的四则运算计算器
- 32bit XP 4g
- Unity3d与dll文件
- javascript学习笔录6(Javascript元素的常用属性)
- Erlang 聊天室程序(六) 设置客户端信息2
- 动态添加删除表格行的js脚本
- String.fromCharCode()练习
- 详解UML中的6大关系(关联、依赖、聚合、组合、泛化、实现)
- 找不到spring的applicationContext.xml异常