-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathParse.py
81 lines (69 loc) · 2.69 KB
/
Parse.py
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
from Token import *
import Value
####### Parse Errors #######
class ParseError:
OK = 0 # Expression has been extracted
CE_ENDS = 1 # compound expression ends
EXPECT_LPAREN = 2 # expect left parenthesis but didn't get it.
EMPTY_EXPRESSION = 3 # EMPTY EXPRESSION
NOT_AN_EXPRESSION = 4
TOKENIZE_ERROR = 5
TOKEN_NORMALLY_ENDS = 6
TOKEN_UNEXPECTED_ENDS = 7
def _parse(tokenIter):
""" _parse() recursively extract the expression from the given
token iterator
//param tokenIter is the token iterator that represents the
stream of tokens
//return a pair, where the first parameter reports the error code
occurs while parsing (OK indicates no error happens);
the second parameter is the extracted expression, which will
be None if error occurs.
"""
try:
token = tokenIter.next()
except StopIteration:
return ParseError.TOKEN_NORMALLY_ENDS, None
# Token type is ERROR
if token.tokenType == Tokens.ERROR:
return ParseError.TOKENIZE_ERROR, token
# All tokens, except the special characters, are considered. special char are: ( ) '
if not token.tokenType in Tokens.specialCharacters:
return ParseError.OK, Value.makeFromToken(token)
# check if this is the end of an expression
if token.tokenType == Tokens.RPAREN:
return ParseError.CE_ENDS, token
"""
# If the token either indicates the expression element
# (operator, parameters)nor the end of expression, then it
# must be the "beginning" of a expression.
if token.tokenType != Tokens.LPAREN:
return ParseError.EXPECT_LPAREN, token
"""
if token.tokenType == Tokens.QUOTE:
error, result = _parse(tokenIter)
return ParseError.OK, Value.makeLiteral(result)
sList = []
# Read parameters, operator is placed together with parameter as the first element of the list
while True:
error, param = _parse(tokenIter)
if error != ParseError.OK:
# reach the end the this expression?
if error == ParseError.CE_ENDS:
break
elif error == ParseError.TOKEN_NORMALLY_ENDS:
return ParseError.TOKEN_UNEXPECTED_ENDS, None #position: the end of the expression
# or real error occurs
else:
return error, param
sList.append(param)
return ParseError.OK, Value.makeList(sList)
def parse(tokenIter):
while True:
error, param = _parse(tokenIter)
# ends normally
if error == ParseError.TOKEN_NORMALLY_ENDS:
break
yield error, param
if error != ParseError.OK:
break