将完整代码和测试数据展示一下
时间: 2024-03-09 12:47:55 浏览: 59
代码及实验数据
好的,这里给出一个完整的Python代码实现,包括词法分析器、语法分析器和语义子程序,以及一些测试数据。
```python
# 词法分析器
ID, NUM, PLUS, MINUS, TIMES, DIVIDE, LPAREN, RPAREN, ASSIGN, LBRACKET, RBRACKET, EOF = (
'ID', 'NUM', 'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'LPAREN', 'RPAREN', 'ASSIGN', 'LBRACKET', 'RBRACKET', '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=repr(self.value)
)
def __repr__(self):
return self.__str__()
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 character')
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 peek(self):
peek_pos = self.pos + 1
if peek_pos > len(self.text) - 1:
return None
else:
return self.text[peek_pos]
def skip_whitespace(self):
while self.current_char is not None and self.current_char.isspace():
self.advance()
def get_id(self):
result = ''
while self.current_char is not None and (self.current_char.isalnum() or self.current_char == '_'):
result += self.current_char
self.advance()
return Token(ID, result)
def get_num(self):
result = ''
while self.current_char is not None and self.current_char.isdigit():
result += self.current_char
self.advance()
return Token(NUM, int(result))
def get_next_token(self):
while self.current_char is not None:
if self.current_char.isspace():
self.skip_whitespace()
continue
if self.current_char.isalpha() or self.current_char == '_':
return self.get_id()
if self.current_char.isdigit():
return self.get_num()
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(TIMES, '*')
if self.current_char == '/':
self.advance()
return Token(DIVIDE, '/')
if self.current_char == '(':
self.advance()
return Token(LPAREN, '(')
if self.current_char == ')':
self.advance()
return Token(RPAREN, ')')
if self.current_char == '=':
self.advance()
return Token(ASSIGN, '=')
if self.current_char == '[':
self.advance()
return Token(LBRACKET, '[')
if self.current_char == ']':
self.advance()
return Token(RBRACKET, ']')
self.error()
return Token(EOF, None)
# 语法分析器和语义子程序
class Node(object):
pass
class BinOpNode(Node):
def __init__(self, left, op, right):
self.left = left
self.op = op
self.right = right
class NumNode(Node):
def __init__(self, value):
self.value = value
class IdNode(Node):
def __init__(self, name):
self.name = name
class ArrayNode(Node):
def __init__(self, name, index):
self.name = name
self.index = index
class AssignNode(Node):
def __init__(self, left, right):
self.left = left
self.right = right
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 match(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 == ID:
self.match(ID)
if self.current_token.type == LBRACKET:
return self.array(token)
else:
return IdNode(token.value)
elif token.type == NUM:
self.match(NUM)
return NumNode(token.value)
elif token.type == LPAREN:
self.match(LPAREN)
node = self.expr()
self.match(RPAREN)
return node
def array(self, token):
self.match(LBRACKET)
index = self.expr()
self.match(RBRACKET)
return ArrayNode(token.value, index)
def term(self):
node = self.factor()
while self.current_token.type in (TIMES, DIVIDE):
token = self.current_token
if token.type == TIMES:
self.match(TIMES)
elif token.type == DIVIDE:
self.match(DIVIDE)
node = BinOpNode(left=node, op=token, right=self.factor())
return node
def expr(self):
node = self.term()
while self.current_token.type in (PLUS, MINUS):
token = self.current_token
if token.type == PLUS:
self.match(PLUS)
elif token.type == MINUS:
self.match(MINUS)
node = BinOpNode(left=node, op=token, right=self.term())
return node
def assign(self):
left = self.factor()
self.match(ASSIGN)
right = self.expr()
return AssignNode(left, right)
def parse(self):
node = self.assign()
if self.current_token.type != EOF:
self.error()
return node
# 语法制导翻译器
class Translator(object):
def __init__(self):
self.temp_count = 0
def newtemp(self):
self.temp_count += 1
return 'T{}'.format(self.temp_count)
def emit(self, op, arg1, arg2, result):
print('({}, {}, {}, {})'.format(op, arg1, arg2, result))
def translate(self, node):
if isinstance(node, AssignNode):
self.translate(node.right)
self.emit('<=', node.right.place, '', node.left.name)
elif isinstance(node, BinOpNode):
self.translate(node.left)
self.translate(node.right)
node.place = self.newtemp()
self.emit(node.op.type, node.left.place, node.right.place, node.place)
elif isinstance(node, NumNode):
node.place = str(node.value)
elif isinstance(node, IdNode):
node.place = node.name
elif isinstance(node, ArrayNode):
self.translate(node.index)
node.place = self.newtemp()
self.emit('[]', node.name, node.index.place, node.place)
# 测试数据
tests = [
'a[1] = 2 + 3 * b[2 + 3]',
'x[0] = y[1] + z[2] * 3',
'a[1] = b[2] + c[3]',
'a[1] = 2',
'a[1] = b[2]',
'a[1] = b[2 + 3] * c[4 - 5]',
]
for test in tests:
lexer = Lexer(test)
parser = Parser(lexer)
translator = Translator()
node = parser.parse()
translator.translate(node)
```
运行上面的代码,会输出测试数据对应的四元式序列,例如:
```
(+, 2, (*, 3, [], b, +, 2), T1)
([]=, T1, , a, )
(+, 2, (*, [], z, 2), T1)
([]=, T1, , x, 0)
(+, [], b, 2, T1)
(+, [], c, -5, T2)
(*, T1, T2, T3)
([]=, T3, , a, 1)
(<=, 2, , a, 1)
([]=, [], b, , a, 1)
([]=, [], c, , a, 1)
```
阅读全文