29
29
from NanoBASIC .tokenizer import Token
30
30
from typing import cast
31
31
from NanoBASIC .nodes import *
32
+ from NanoBASIC .errors import ParserError
32
33
33
34
34
35
class Parser :
35
- class ParserError (Exception ):
36
- def __init__ (self , message : str , token : Token ):
37
- self .message = message
38
- self .line_num = token .line_num
39
- self .column = token .col_start
40
-
41
- def __str__ (self ):
42
- return (f"{ self .message } Occurred at line { self .line_num } "
43
- f"and column { self .column } " )
44
-
45
36
def __init__ (self , tokens : list [Token ]):
46
37
self .tokens = tokens
47
38
self .token_index : int = 0
@@ -53,8 +44,8 @@ def out_of_tokens(self) -> bool:
53
44
@property
54
45
def current (self ) -> Token :
55
46
if self .out_of_tokens :
56
- raise (Parser . ParserError (f"No tokens after "
57
- f"{ self .previous .kind } " , self .previous ))
47
+ raise (ParserError (f"No tokens after "
48
+ f"{ self .previous .kind } " , self .previous ))
58
49
return self .tokens [self .token_index ]
59
50
60
51
@property
@@ -65,8 +56,8 @@ def consume(self, kind: TokenType) -> Token:
65
56
if self .current .kind is kind :
66
57
self .token_index += 1
67
58
return self .previous
68
- raise Parser . ParserError (f"Expected { kind } after { self .previous } "
69
- f"but got { self .current } ." , self .current )
59
+ raise ParserError (f"Expected { kind } after { self .previous } "
60
+ f"but got { self .current } ." , self .current )
70
61
71
62
def parse (self ) -> list [Statement ]:
72
63
statements : list [Statement ] = []
@@ -93,8 +84,8 @@ def parse_statement(self, line_id: int) -> Statement:
93
84
return self .parse_gosub (line_id )
94
85
case TokenType .RETURN_T :
95
86
return self .parse_return (line_id )
96
- raise Parser . ParserError ("Expected to find start of statement." ,
97
- self .current )
87
+ raise ParserError ("Expected to find start of statement." ,
88
+ self .current )
98
89
99
90
# PRINT "COMMA",SEPARATED,7154
100
91
def parse_print (self , line_id : int ) -> PrintStatement :
@@ -110,8 +101,8 @@ def parse_print(self, line_id: int) -> PrintStatement:
110
101
printables .append (expression )
111
102
last_col = expression .col_end
112
103
else :
113
- raise Parser . ParserError ("Only strings and numeric expressions "
114
- "allowed in print list." , self .current )
104
+ raise ParserError ("Only strings and numeric expressions "
105
+ "allowed in print list." , self .current )
115
106
# Comma means there's more to print
116
107
if not self .out_of_tokens and self .current .kind is TokenType .COMMA :
117
108
self .consume (TokenType .COMMA )
@@ -166,15 +157,15 @@ def parse_return(self, line_id: int) -> ReturnStatement:
166
157
# NUMERIC_EXPRESSION BOOLEAN_OPERATOR NUMERIC_EXPRESSION
167
158
def parse_boolean_expression (self ) -> BooleanExpression :
168
159
left = self .parse_numeric_expression ()
169
- if self .current .kind in [ TokenType .GREATER , TokenType .GREATER_EQUAL , TokenType .EQUAL ,
170
- TokenType .LESS , TokenType .LESS_EQUAL , TokenType .NOT_EQUAL ] :
160
+ if self .current .kind in { TokenType .GREATER , TokenType .GREATER_EQUAL , TokenType .EQUAL ,
161
+ TokenType .LESS , TokenType .LESS_EQUAL , TokenType .NOT_EQUAL } :
171
162
operator = self .consume (self .current .kind )
172
163
right = self .parse_numeric_expression ()
173
164
return BooleanExpression (line_num = left .line_num ,
174
165
col_start = left .col_start , col_end = right .col_end ,
175
166
operator = operator .kind , left_expr = left , right_expr = right )
176
- raise Parser . ParserError (f"Expected boolean operator but found "
177
- f"{ self .current .kind } ." , self .current )
167
+ raise ParserError (f"Expected boolean operator but found "
168
+ f"{ self .current .kind } ." , self .current )
178
169
179
170
def parse_numeric_expression (self ) -> NumericExpression :
180
171
left = self .parse_term ()
@@ -235,7 +226,7 @@ def parse_factor(self) -> NumericExpression:
235
226
self .consume (TokenType .OPEN_PAREN )
236
227
expression = self .parse_numeric_expression ()
237
228
if self .current .kind is not TokenType .CLOSE_PAREN :
238
- raise Parser . ParserError ("Expected matching close parenthesis." , self .current )
229
+ raise ParserError ("Expected matching close parenthesis." , self .current )
239
230
self .consume (TokenType .CLOSE_PAREN )
240
231
return expression
241
232
elif self .current .kind is TokenType .MINUS :
@@ -244,4 +235,4 @@ def parse_factor(self) -> NumericExpression:
244
235
return UnaryOperation (line_num = minus .line_num ,
245
236
col_start = minus .col_start , col_end = expression .col_end ,
246
237
operator = TokenType .MINUS , expr = expression )
247
- raise Parser . ParserError ("Unexpected token in numeric expression." , self .current )
238
+ raise ParserError ("Unexpected token in numeric expression." , self .current )
0 commit comments