java开发简单解释器,实现一个简单的解释器(6)

译自:https://ruslanspivak.com/lsbasi-part6/

(已获得作者授权)

今天,我们通过将带括号的表达式添加到语法,并实现一个能够计算任意深度嵌套表达式的解释器来结束对算术表达式的讨论。

让我们开始吧!

首先,让我们修改语法以支持括号内的表达式,正如在第5部分中所记得的那样,factor规则用于表达式中的基本单位,在那篇文章中,我们仅有的基本单位是整数,今天我们添加了另外一个基本单位,也就是带括号的表达式。

这是我们更新的语法:

f4292a70ba5cb9c05bb25e84866df16a.png

expr和term与第5部分完全相同,唯一的变化是factor的产生式,其中LPAREN表示左括号'(',RPAREN表示右括号')',而括号之间的非终结符expr表示expr规则。

这是factor的更新语法图:

84e2f895b091de801109ccfe81b07810.png

因为expr和term的语法规则没有改变,所以它们的语法图看起来与第5部分中的相同:

7f1d8ea27fbdb1d6422f57c4e87ef3e6.png

这是我们新语法的一个有趣功能:递归,如果尝试推导表达式2 * (7 + 3),则将从expr起始符开始,之后将递归地再次使用expr规则来推导表达式(7 + 3)这一部分。

让我们根据语法分解表达式2 *(7 + 3):

86509f5a658847109cded87c75043265.png

好的,让我们开始将新的更新语法转换为代码。

以下是对上一篇文章代码的主要更改:

1、对Lexer进行修改,以返回另外两个标记:LPAREN用于左括号,而RPAREN用于右括号。

2、对解释器的factor函数进行修改,可以解析(parse)除整数以外的带括号的表达式。

这是计算器的完整代码,可以计算任意数量的加,减,乘和除整数运算以及带有任意深度嵌套的带括号的表达式:

# Token types

#

# EOF (end-of-file) token is used to indicate that

# there is no more input left for lexical analysis

INTEGER, PLUS, MINUS, MUL, DIV, LPAREN, RPAREN, EOF = (

'INTEGER', 'PLUS', 'MINUS', 'MUL', 'DIV', '(', ')', 'EOF'

)

class Token(object):

def __init__(self, type, value):

self.type = type

self.value = value

def __str__(self):

"""String representation of the class instance.

Examples:

Token(INTEGER, 3)

Token(PLUS, '+')

Token(MUL, '*')

"""

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

# client string input, e.g. "4 + 2 * 3 - 6 / 2"

self.text = text

# self.pos is an index into self.text

self.pos = 0

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

def error(self):

raise Exception('Invalid character')

def advance(self):

"""Advance the `pos` pointer and set the `current_char` variable."""

self.pos += 1

if self.pos > len(self.text) - 1:

self.current_char = None # Indicates end of input

else:

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

def skip_whitespace(self):

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

self.advance()

def integer(self):

"""Return a (multidigit) integer consumed from the input."""

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

"""Lexical analyzer (also known as scanner or tokenizer)

This method is responsible for breaking a sentence

apart into tokens. One token at a time.

"""

while self.current_char is not None:

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

b739ec46bb5c46d9c0aa4ce35ba1ea56.png

关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。

本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。

[实现一个简单的解释器(6)]http://www.zyiz.net/tech/detail-113704.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值