开发自己的编程语言 —— 计算器(一)

本文借助计算器项目介绍如何使用rply库。该计算器是支持加减运算的解释器程序,可帮助学习构建简单词法和语法分析器。文中给出代码清单,并详细解释了引入模块、构建词法解析器等步骤,包括如何将代码解析成Token对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天我们借用一个计算器项目来学习如何使用rply库。这里所谓的计算器是一个支持加减运算的解释器程序,可以很简单的让我们学会使用rply构建简单的词法和语法分析器。

小学辅导 https://baike.hfjy.com/primary/
初中辅导 https://baike.hfjy.com/middle/
高中辅导 https://baike.hfjy.com/high/

代码清单

from rply import ParserGenerator, LexerGenerator
from rply.token import BaseBox

lg = LexerGenerator()
lg.add(“PLUS”, r"+")
lg.add(“MINUS”, r"-")
lg.add(“NUMBER”, r"\d+")

lg.ignore(r"\s+")

pg = ParserGenerator([“NUMBER”, “PLUS”, “MINUS”],
precedence=[(“left”, [‘PLUS’, ‘MINUS’])], cache_id=“myparser”)

@pg.production(“main : expr”)
def main§:
return p[0]

@pg.production(“expr : expr PLUS expr”)
@pg.production(“expr : expr MINUS expr”)
def expr_op§:
lhs = p[0].getint()
rhs = p[2].getint()
if p[1].gettokentype() == “PLUS”:
return BoxInt(lhs + rhs)
elif p[1].gettokentype() == “MINUS”:
return BoxInt(lhs - rhs)
else:
raise AssertionError(“This is impossible, abort the time machine!”)

@pg.production(“expr : NUMBER”)
def expr_num§:
return BoxInt(int(p[0].getstr()))

lexer = lg.build()
parser = pg.build()

class BoxInt(BaseBox):
def init(self, value):
self.value = value

def getint(self):
    return self.value

代码解释

1、开始编写之前我们要引入需要的模块。

from rply import ParserGenerator, LexerGenerator
from rply.token import BaseBox
其中LexerGenerator用于构建词法解析器;ParserGenerator用于构建语法分析器;BaseBox用于构建语法树。

2、一般来说我们会先构建一个词法解析器,它会帮我们把代码中的内容解析成单个单个的Token对象,例如1 + 2可以被解析成[NUMBER, PLUS, NUMBER]。

lg = LexerGenerator()
lg.add(“PLUS”, r"+")
lg.add(“MINUS”, r"-")
lg.add(“NUMBER”, r"\d+")

lg.ignore(r"\s+")

lexer = lg.build()

mycode = ‘1 + 1’
mytoken = lexer.lex(mycode)
for token in mytoken:
print(token)
运行输出:

Token(‘NUMBER’, ‘1’)
Token(‘PLUS’, ‘+’)
Token(‘NUMBER’, ‘1’)
在上面的代码中先使用lg = LexerGenerator()实例一个对象,然后用add属性方法添加规则,add方法的第一个参数是Token的类型,第二个是正则表达式规则,如果有代码被正则表达式匹配,就会生成一个对应的Token对象而对象的类型则由第一个参数决定。

lg.ignore(r"\s+")则是用于忽略一些代码内容,一般会设置成忽略空格等空白字符。

最后使用lexer = lg.build()构建解析器。

在使用的时候传入代码字符串到lexer的属性方法lex就会得到一个生成器对象,可以用for语句取出Token对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值