一、实验目的

1.熟悉体系结构的风格的概念

2.理解和应用管道过滤器型的风格。

3、理解解释器的原理

4、理解编译器模型

二、实验环境

硬件:

软件:Python或任何一种自己喜欢的语言

三、实验内容

1、实现“四则运算”的简易翻译器。

结果要求:

1)实现加减乘除四则运算,允许同时又多个操作数,如:2+3*5-6 结果是11

2)被操作数为整数,整数可以有多位

3)处理空格

4)输入错误显示错误提示,并返回命令状态“CALC”

图1    实验结果示例

加强练习:

1、有能力的同学,可以尝试实现赋值语句,例如x=2+3*5-6,返回x=11。(注意:要实现解释器的功能,而不是只是显示)

2、尝试实现自增和自减符号,例如x++

2、采用管道-过滤器(Pipes and Filters)风格实现解释器

                  图2  管道-过滤器风格

                图 3  编译器模型示意图

本实验,实现的是词法分析和语法分析两个部分。

四、实验步骤:

INTEGER, PLUS, MINUS, MUL, DIV, LPAREN, RPAREN, EOF,VARIABLE,EQUALITY,INCREMENT,REDUCE = ('INTEGER', 'PLUS', 'MINUS', 'MUL', 'DIV', 'LPAREN', 'RPAREN', 'EOF','VARIABLE','EQUALITY','INCREMENT','REDUCE')
class Token(object):    def __init__(self,type,value):        self.type = type        self.value = value    # toString    def __str__(self):        return 'Token({type},{value})'.format(            type=self.type,            value = self.value        )

class Lexer(object):    # 词法分析器    # 给每个词打标记    # text为输入的表达式    def __init__(self, text):        self.text = text        # pos为当前位置        self.pos = 0        # current_char为当前字符        self.current_char = self.text[self.pos]    # 取字符错误时调用的方法    def error(self):        # raise 抛出异常        raise Exception('Invalid Char')    #前进的方法,即取下一个字符    def advance(self):        # 往下走,取值        self.pos += 1        if self.pos > len(self.text) - 1:            self.current_char = None        else:            self.current_char = self.text[self.pos]

    def variable(self):        # 变量处理        variable = ''        while self.current_char is not None and self.current_char.isalpha():            variable = variable + self.current_char            # 往下走,取值            self.advance()            # 取值完毕后,将该变量存入字典中            if variable not in variables:                variables[variable] = None        return variable    def integer(self):        # 多位整数处理        result = ''        while self.current_char is not None and self.current_char.isdigit():            result = result + self.current_char            # 往下走,取值            self.advance()        return int(result)    # 处理输入时的非法空格    def deal_space(self):        # 循环遍历,遇到空格则跳过,取下一个字符        while self.current_char is not None and self.current_char.isspace():            self.advance()

    def get_next_token(self):        # 打标记:1)pos+1,2)返回Token(类型,数值)        while self.current_char is not None:            # 空格处理            if self.current_char.isspace():                self.deal_space()            # 数字处理(判断是否为多位整数)            if self.current_char.isdigit():                return Token(INTEGER, self.integer())            # 加号处理Plus            if self.current_char == '+':                # # 判断是自增还是加号                # if self.get_next_token() '+':                #     self.advance()                #     return Token(PLUS, '+')                self.advance()                return Token(PLUS, '+')            # 减号处理Minus            if self.current_char == '-':                self.advance()                return Token(MINUS, '-')            # 左括号            if self.current_char == '(':                self.advance()                return Token(LPAREN,'(')            # 右括号            if self.current_char == ')':                self.advance()                return Token(RPAREN,')')            # 乘号            if self.current_char == '*':                self.advance()                return Token(MUL,'*')            # 除号            if self.current_char == '/':                self.advance()                return Token(DIV,'/')            # 若是判断出字符则进入变量获取的方法            if self.current_char.isalpha():                return Token(VARIABLE,self.variable())            # 等号            if self.current_char == '=':                self.advance()                return Token(EQUALITY,'EQUALITY')            # # 自增            # if self.current_char == '++':            #     self.advance()            #     return Token(EQUALITY,'EQUALITY')

            # 其余均为非法字符            self.error()        # 取到None字符 返回一个空的Token  表示循环结束        return Token(EOF, None)

class Interpreter(object):    # 句法分析    # 语法树    # 语法树中的一个参数为词法分析器Lexer    def __init__(self, lexer):        self.lexer = lexer        self.current_token = self.lexer.get_next_token()

    def error(self):        raise Exception('Invalid Syntax')    # 当当前Token取值完毕    # 删除当前的Token,取下一个Token的值    def eat(self, token_type):        # 跳过与当前相同的Token,取下一个Token        if self.current_token.type == token_type:            self.current_token = self.lexer.get_next_token()        else:            # 若在删除的过程中出错,会引起整体的错误,故抛错            self.error()    # 工厂方法    def factor(self):        token = self.current_token        # 判断当前要删除的Token类型        if token.type == INTEGER:            self.eat(INTEGER)            return token.value        # 将类型为Variable的变量返回        if token.type == VARIABLE:            self.eat(VARIABLE)            return variables[token.value]        # 左括号        elif token.type == LPAREN:            self.eat(LPAREN)            result = self.expr()            self.eat(RPAREN)            return result

    def term(self):        result = self.factor()        while self.current_token.type in (MUL, DIV):            token = self.current_token            if token.type == MUL:                self.eat(MUL)                result = result * self.factor()            if token.type == DIV:                self.eat(DIV)                result = result / self.factor()        return result

    def expr(self):        result = self.term()        while self.current_token.type in (PLUS, MINUS):            token = self.current_token            if token.type == PLUS:                self.eat(PLUS)                result = result + self.term()            if token.type == MINUS:                self.eat(MINUS)                result = result - self.term()        return result    def assignment(self):        if self.current_token.type == VARIABLE:            var = self.current_token.value            self.eat(VARIABLE)            if self.current_token.type == EQUALITY:                self.eat(EQUALITY)                variables[var] = self.expr()            return vardef printResult(text):    lexer = Lexer(text)    variableKey = Interpreter(lexer).assignment()    print(variableKey,"=",variables[variableKey])

def main():    while True:        try:            text = input('calc_> ')        except EOFError:            break

        if not text:            continue        # try:        printResult(text)        # except Exception:        #     print('Invalid Syntax')

if __name__ == '__main__':    main()

转载于:https://www.cnblogs.com/RealKing/p/7780189.html

130242014022 蓝宏铮 第2次实验相关推荐

  1. 20145231熊梓宏 《网络对抗》 实验四 恶意代码分析

    20145231熊梓宏 <网络对抗> 实验四 恶意代码分析 基础问题回答 1.如果在工作中怀疑一台主机上有恶意代码,但只是猜想,所有想监控下系统一天天的到底在干些什么.请设计下你想监控的操 ...

  2. c语言实验报告函数和宏定义,第六章 实验报告(函数与宏定义)

    ##C程序设计实验报告 ###一.实验项目: 1.编写由三角形三边求面积的函数 2.编写求N阶乘的函数 3.求两个整数的最大公约数 4.打印输出三角形 5.求500以内的所有亲密数对 ##姓名:戴求  ...

  3. 计算机组成原理秒表设计实验,计算机组成原理实验2.4计数器赖晓铮剖析.ppt

    计算机组成原理实验2.4计数器赖晓铮剖析 计算机组成原理 实验系列 一.总线与寄存器 二.进位加法器 三.比较器(仲裁器) 四.计数器 五.运算器 六.存储器 七.时序发生器 八.微程序控制器 九.硬 ...

  4. 计算机组成原理字发生器,计算机组成原理实验2.7时序发生器赖晓铮剖析.ppt

    计算机组成原理实验2.7时序发生器赖晓铮剖析 计算机组成原理 实验系列 一.总线与寄存器 二.进位加法器 三.比较器(仲裁器) 四.计数器 五.运算器 六.存储器 七.时序发生器 八.微程序控制器 九 ...

  5. 子程序调用与宏定义的异同_微机原理 宏指令及子程序设计实验:宏指令和子程序的区别...

    西安邮电学院 微机原理实验报告 题 目: 宏指令及子程序设计实验 院系名称: 班 级: 学生姓名: 学号(8位): 指导教师: 2.5 宏令及子程序设计实验 2.5.1 实验目的 1.熟悉宏指令.宏定 ...

  6. JoVE微生物组专刊征稿,写方法拍视频教程发SCI(宏基因组公众号专属福利)

    JoVE 视频实验杂志 官网:https://www.jove.com/ 包括上万个实验和分析方法视频,还有几十个领域的数百个专业视频教程资源. 这个杂志被SCI收录了吗?必须的.杂志在Web of ...

  7. python面向对象实验报告_20192310 实验三《Python程序设计》实验报告

    学号 2020-2021-1 <数据结构与面向对象程序设计>实验三报告 课程:<程序设计与数据结构> 班级: 1923 姓名: 严嘉钰 学号:20192310 实验教师:王志强 ...

  8. 利用DOCX文档远程模板注入执行宏代码

    利用DOCX文档远程模板注入执行宏代码 简介 本地文件中在没有宏代码的情况下,攻击者可以尝试执行远程文件中宏代码.其中来自APT28的最新样本将此技术展现的淋漓尽致.该样本是docx文件,文件内没有任 ...

  9. 数电实验一-初识Multisim和Basys3

    特别说明:该系列内容均是本人实验记录,无盗取侵权之嫌,仅供参考,请多动手实践! 一.实验目的 详见报告 二.实验仪器设备 详见报告 三.实验设计过程 使用Multisim为Basys3板卡创建一个PL ...

最新文章

  1. catia三维轴承_浅谈基于CATIA二次开发的单排四点接触球轴承三维设计论文
  2. 解决CSV文件中长数字以科学记数格式保存问题
  3. cocos2d-x jsbinding 在线更新策略设计
  4. 上如何刻字_校园石阶上被人刻了1700多个字?!这次网友却说好
  5. 基于docker安装tensorflow
  6. PAT乙级题目答案汇总PAT (Basic Level) Practice (中文)
  7. 第22天学习Java的笔记-继承
  8. 针对C++和Delphi的LiveBindings一瞥
  9. json.stringfy()和json.parse()
  10. linux服务器系统_利用Zabbix监控系统监测Linux服务器系统时间是否准确完美实现...
  11. mysql优化之 EXPLAIN(一)
  12. Vue之webpack之vue
  13. Zookeeper C API 指南三(回调函数)
  14. 老毛子Padavan网段LAN修改
  15. win7如何添加终端服务器,Win7怎么添加windows超级终端?
  16. 【目标检测适用】Pascal Voc(07+12)联合训练并在07上测试
  17. 微信公众平台的设计与开发之道
  18. 输入法半角和全角的快捷转换_搜狗输入法经常用到的冷门小技巧,复制文章空白行取消方法...
  19. Canvas3——绘制渐变图形与绘制变形图形
  20. com.googlecode.genericdao

热门文章

  1. 《机电传动控制》----学习笔记六
  2. python基础知识-列表,元组,字典
  3. 解题报告 Diamonds
  4. Spring Android 1.0.0.M3 发布
  5. 关于“收获”啰嗦几句。
  6. 浅谈vue $mount()
  7. JavaScriptBreak 语句 continue 语句
  8. angular 使用rxjs 监听同级兄弟组件数据变化
  9. 【BZOJ 3098】 Hash Killer II
  10. Android ListView避免多线程加载一个同一资源