Spaces:
Runtime error
Runtime error
File size: 3,611 Bytes
753d525 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | class Parser:
def __init__(self, tokens):
self.tokens = tokens
self.pos = 0
self.errors = []
def peek(self):
if self.pos >= len(self.tokens):
return ('EOF', None)
return self.tokens[self.pos]
def consume(self, expected_type=None):
token = self.peek()
if expected_type and token[0] != expected_type:
self.errors.append(f"Syntax Error: Expected {expected_type} but got {token[0]}")
if token[0] != 'EOF':
self.pos += 1
return token
def parse(self):
nodes = []
while self.peek()[0] != 'EOF':
stmt = self.statement()
if stmt:
nodes.append(stmt)
return nodes
def statement(self):
t_type, val = self.peek()
if t_type == 'LBRACE':
return self.block()
# --- FIXED HERE: Accept all primitive data types ---
if t_type == 'KEYWORD' and val in ('int', 'float', 'char', 'bool'):
return self.declaration()
if t_type == 'ID':
return self.assignment()
if t_type == 'KEYWORD' and val == 'print':
return self.print_stmt()
if t_type != 'EOF':
self.errors.append(f"Syntax Error: Invalid statement start '{val}'")
self.consume()
return None
def block(self):
self.consume('LBRACE')
statements = []
while self.peek()[0] != 'RBRACE' and self.peek()[0] != 'EOF':
stmt = self.statement()
if stmt:
statements.append(stmt)
self.consume('RBRACE')
return ('BLOCK', statements)
def declaration(self):
self.consume('KEYWORD') # Dynamically consumes 'int', 'float', 'char', or 'bool'
name = self.consume('ID')[1]
if self.peek()[0] == 'ASSIGN':
self.consume('ASSIGN')
expr = self.expression()
self.consume('SEMI')
return ('DECL_ASSIGN', name, expr) # Keeps the exact same tuple shape
self.consume('SEMI')
return ('DECL', name)
def assignment(self):
name = self.consume('ID')[1]
self.consume('ASSIGN')
expr = self.expression()
self.consume('SEMI')
return ('ASSIGN', name, expr)
def print_stmt(self):
self.consume('KEYWORD')
self.consume('LPAREN')
expr = self.expression()
self.consume('RPAREN')
self.consume('SEMI')
return ('PRINT', expr)
def expression(self):
node = self.term()
while self.peek()[1] in ('+', '-'):
op = self.consume()[1]
right = self.term()
node = ('BINOP', op, node, right)
return node
def term(self):
node = self.factor()
while self.peek()[1] in ('*', '/'):
op = self.consume()[1]
right = self.factor()
node = ('BINOP', op, node, right)
return node
def factor(self):
token = self.peek()
if token[0] == 'NUMBER' or token[0] == 'ID':
return self.consume()[1]
elif token[0] == 'LPAREN':
self.consume('LPAREN')
node = self.expression()
self.consume('RPAREN')
return node
self.errors.append(f"Syntax Error: Expected Number or ID but got {token[0]}")
self.consume()
return None |