天天看點

java開發簡單解釋器,實作一個簡單的解釋器(6)

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

(已獲得作者授權)

今天,我們通過将帶括号的表達式添加到文法,并實作一個能夠計算任意深度嵌套表達式的解釋器來結束對算術表達式的讨論。

讓我們開始吧!

首先,讓我們修改文法以支援括号内的表達式,正如在第5部分中所記得的那樣,factor規則用于表達式中的基本機關,在那篇文章中,我們僅有的基本機關是整數,今天我們添加了另外一個基本機關,也就是帶括号的表達式。

這是我們更新的文法:

java開發簡單解釋器,實作一個簡單的解釋器(6)

expr和term與第5部分完全相同,唯一的變化是factor的産生式,其中LPAREN表示左括号'(',RPAREN表示右括号')',而括号之間的非終結符expr表示expr規則。

這是factor的更新文法圖:

java開發簡單解釋器,實作一個簡單的解釋器(6)

因為expr和term的文法規則沒有改變,是以它們的文法圖看起來與第5部分中的相同:

java開發簡單解釋器,實作一個簡單的解釋器(6)

這是我們新文法的一個有趣功能:遞歸,如果嘗試推導表達式2 * (7 + 3),則将從expr起始符開始,之後将遞歸地再次使用expr規則來推導表達式(7 + 3)這一部分。

讓我們根據文法分解表達式2 *(7 + 3):

java開發簡單解釋器,實作一個簡單的解釋器(6)

好的,讓我們開始将新的更新文法轉換為代碼。

以下是對上一篇文章代碼的主要更改:

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

java開發簡單解釋器,實作一個簡單的解釋器(6)

關于找一找教程網

本站文章僅代表作者觀點,不代表本站立場,所有文章非營利性免費分享。

本站提供了軟體程式設計、網站開發技術、伺服器運維、人工智能等等IT技術文章,希望廣大程式員努力學習,讓我們用科技改變世界。

[實作一個簡單的解釋器(6)]http://www.zyiz.net/tech/detail-113704.html