码迷,mamicode.com
首页 > 其他好文 > 详细

130242014041-曾子云-实验二

时间:2017-10-29 00:34:26      阅读:189      评论:0      收藏:0      [点我收藏+]

标签:name   词法分析   词法   elf   cal   one   pes   turn   for   

一、实验目的

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 = (

‘INTEGER‘, ‘PLUS‘, ‘MINUS‘, ‘MUL‘, ‘DIV‘, ‘LPAREN‘, ‘RPAREN‘, ‘EOF‘)

 

 

class Token(object):

    def __init__(self, type, value):

        self.type = type

        self.value = value

 

    def __str__(self):

        return ‘Token({type},{value})‘.format(

            type=self.type,

            value=self.value

        )

 

 

class Lexer(object):

    # 词法分析器

    # 给每个词打标记

    def __init__(self, text):

        self.text = text

        self.pos = 0

        self.current_char = self.text[self.pos]

 

    def error(self):

        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 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())

            if self.current_char == ‘+‘:

                self.advance()

                return Token(PLUS, ‘+‘)

            if self.current_char == ‘-‘:

                self.advance()

                return Token(MINUS, ‘-‘)

            if self.current_char == ‘*‘:

                self.advance()

                return Token(MUL, ‘*‘)

            if self.current_char == ‘/‘:

                self.advance()

                return Token(DIV, ‘/‘)

            if self.current_char == ‘(‘:

                self.advance()

                return Token(LPAREN, ‘(‘)

            if self.current_char == ‘)‘:

                self.advance()

                return Token(RPAREN, ‘)‘)

            self.error()

        return Token(EOF, None)

 

 

class Interpreter(object):

    # 句法分析

    # 语法树

    def __init__(self, lexer):

        self.lexer = lexer

        self.current_token = self.lexer.get_next_token()

 

    def error(self):

        raise Exception(‘Invalid Syntax‘)

 

    def eat(self, token_type):

        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

        if token.type == INTEGER:

            self.eat(INTEGER)

            return 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):

        try:

            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

        except Exception as e:

            print("输入错误,请重新输入")

 

 

def main():

    while True:

        try:

            text = input(‘calc_> ‘)

        except EOFError:

            Interpreter.error()

            break

        if not text:

            continue

        lexer = Lexer(text)

        result = Interpreter(lexer).expr()

        if (result is not None):

            print(result)

 

 

if __name__ == ‘__main__‘:

main()

 

 

运算截图:

 技术分享

130242014041-曾子云-实验二

标签:name   词法分析   词法   elf   cal   one   pes   turn   for   

原文地址:http://www.cnblogs.com/zy7445/p/7748661.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!