文档章节

解释器实例之算数计算(一)

shawnplaying
 shawnplaying
发布于 2016/04/18 22:17
字数 449
阅读 31
收藏 0

实现一个简单的解释器,其中只包含整数和加减乘除符号,无括号,并且乘除优先级最高。

参考这里:https://github.com/rspivak/lsbasi

# Token types
#
# EOF (end-of-file) token is used to indicate that
# there is no more input left for lexical analysis
INTEGER, PLUS,MINUS,MULT, DIV, EOF = 'INTEGER','PLUS','MINUS', 'MULT','DIV', 'EOF'


class Token(object):
    def __init__(self, type, value):
        # token type: INTEGER, PLUS, or EOF
        self.type = type
        # token value: 0, 1, 2. 3, 4, 5, 6, 7, 8, 9, '+', or None
        self.value = value

    def __str__(self):
        """String representation of the class instance.
        Examples:
            Token(INTEGER, 3)
            Token(PLUS '+')
        """
        return 'Token({type}, {value})'.format(
            type=self.type,
            value=repr(self.value)
        )

    def __repr__(self):
        return self.__str__()

class Lexer(object):
    def __init__(self,text):
        self.text=text
        self.current_pos=0
        self.current_char=self.text[self.current_pos]

    def error(self):
        raise Exception('Invalid character!')
    def advance(self):
        self.current_pos+=1
        if self.current_pos > len(self.text)-1 :
            self.current_char=None
        else:
            self.current_char=self.text[self.current_pos]

    def skip_whitespace(self):
        while self.current_char is not None and self.current_char.isspace():
            self.advance()

    def integer(self):
        result=''
        while self.current_char is not None and self.current_char.isdigit():
            result+=self.current_char
            self.advance()
        return int(result)

    def get_next_token(self):
        while self.current_char is not None:
            #print('get_next_token---->'+self.current_char)
            if self.current_char.isspace():
                self.skip_whitespace()
                continue
            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(MULT,'*')
            if self.current_char=='/':
                self.advance()
                return Token(DIV,'/')
            self.error()

        return Token(EOF,None)

class Parser(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):
        #print('eat---->'+self.current_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
        self.eat(INTEGER)
        return token.value

    def term(self):
        r=self.factor()
        #print('term---->'+self.current_token.type)
        while self.current_token.type != EOF :
            if self.current_token.type==MULT:
                self.eat(MULT)
                r=r*self.factor()
            elif self.current_token.type==DIV:
                self.eat(DIV)
                r=r/self.factor()
            else:
                break
                #print("term error....."+self.current_token.type)
        return r

    def expr(self):
        t=self.term()
        #print('expr---->'+str(t))
        while self.current_token.type != EOF :
            if self.current_token.type==PLUS:
                self.eat(PLUS)
                t=t+self.term()
            elif self.current_token.type==MINUS:
                self.eat(MINUS)
                t=t-self.term()
            else:
                #????
                pass
        return t

    def parse(self):
        return self.expr()

def main():
    while True:
        try:
            # To run under Python3 replace 'raw_input' call
            # with 'input'
            text = raw_input('calc> ')
        except EOFError:
            break
        if not text:
            continue

        parser = Parser(Lexer(text))
        result=parser.parse()
        print(result)


if __name__ == '__main__':
    main()


© 著作权归作者所有

shawnplaying
粉丝 15
博文 128
码字总数 70642
作品 0
海淀
系统管理员
私信 提问
bash特性中多命令执行的逻辑关系和bash脚本编程之编程

bash的特性之多命令执行的逻辑关系: 1.命令替换 COMMAND1 $(COMMAND2) (先执行COMMAND2,把COMMAND2的执行结果传递给COMMAND1来执行) 2.管道 COMMAND1 | COMMAND2 | COMMAND3 ... (先执行C...

花花很漂漂
2017/11/16
0
0
自己手动编写一个简单的解释器 Part 3

早上起来的时候我自顾自地想着:“为什么我们会发现学一门新的技能很困难呢?” 我认为这并不仅仅是因为辛苦的工作。我认为其中的一个原因可能是我们花了很多时间和辛苦的工作用在通过阅读文...

Aaron74
2015/08/17
4.3K
5
Shell编程基础

说到编程,我们大家都不会陌生,但是在Linux中,我们主要做的是脚本的编写。当然了,想要了解Linux的脚本编写,我们得先来说说多命令执行的逻辑关系。 1.命令替换 COMMAND1 $(COMMAND2) 2.管...

long44
2017/11/17
0
0
解释器实例之算数计算(二)

实现一个简单的解释器,其中只包含整数和加减乘除符号,包含了括号,并且乘除优先级最高。 参考这里:https://ruslanspivak.com/lsbasi-part6/ # Token types EOF (end-of-file) token is u...

shawnplaying
2016/04/18
36
0
解释器实例之算数计算(三)

整个过程是,先构造语法树,然后再前序遍历语法树进行计算。 参考:https://ruslanspivak.com/lsbasi-part7/ # Token types EOF (end-of-file) token is used to indicate that there is no...

shawnplaying
2016/04/23
20
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周六乱弹 —— 早上儿子问我他是怎么来的

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @凉小生 :#今日歌曲推荐# 少点戾气,愿你和这个世界温柔以待。中岛美嘉的单曲《僕が死のうと思ったのは (曾经我也想过一了百了)》 《僕が死の...

小小编辑
今天
182
4
Excption与Error包结构,OOM 你遇到过哪些情况,SOF 你遇到过哪些情况

Throwable 是 Java 中所有错误与异常的超类,Throwable 包含两个子类,Error 与 Exception 。用于指示发生了异常情况。 Java 抛出的 Throwable 可以分成三种类型。 被检查异常(checked Exc...

Garphy
今天
10
0
计算机实现原理专题--二进制减法器(二)

在计算机实现原理专题--二进制减法器(一)中说明了基本原理,现准备说明如何来实现。 首先第一步255-b运算相当于对b进行按位取反,因此可将8个非门组成如下图的形式: 由于每次做减法时,我...

FAT_mt
昨天
6
0
好程序员大数据学习路线分享函数+map映射+元祖

好程序员大数据学习路线分享函数+map映射+元祖,大数据各个平台上的语言实现 hadoop 由java实现,2003年至今,三大块:数据处理,数据存储,数据计算 存储: hbase --> 数据成表 处理: hive --> 数...

好程序员官方
昨天
7
0
tabel 中含有复选框的列 数据理解

1、el-ui中实现某一列为复选框 实现多选非常简单: 手动添加一个el-table-column,设type属性为selction即可; 2、@selection-change事件:选项发生勾选状态变化时触发该事件 <el-table @sel...

everthing
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部