-
Notifications
You must be signed in to change notification settings - Fork 0
/
lisp_parser.py
144 lines (112 loc) · 3.71 KB
/
lisp_parser.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
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import ply.yacc as yacc
from lisp_lex import tokens
""" Lambda Structure:
(lambda (arg-variables...)
[documentation-string]
[interactive-declaration]
body-forms...)
"""
file = open('res', 'a')
file.close
def p_expresion_lambda(p):
"""expresion_lambda : LPAREN LAMBDA LPAREN arguments RPAREN TEXT body RPAREN
| LPAREN LAMBDA LPAREN arguments RPAREN body RPAREN"""
print("Correct!")
file = open('res', 'a')
file.write("Correct!\n")
file.close()
def p_body(p):
""" body : expresion_list
| expresion_list body
| factor"""
def p_expresion(p):
""" expresion : LPAREN factor_list RPAREN
| LPAREN operator factor_list RPAREN
| LPAREN operator expresion_list RPAREN
| LPAREN FUNCTION factor_list RPAREN
| LPAREN FUNCTION expresion_list RPAREN
| LPAREN ifs RPAREN"""
def p_expresion_list(p):
""" expresion_list : expresion
| expresion expresion_list
| factor_list """
def p_ifs(p):
""" ifs : IF booleans expresion expresion
| IF expresion expresion expresion
| IF expresion expresion """
def p_arguments(p):
""" arguments : symbol_list
| optional_list
| symbol_list optional_list
| rest_list
| symbol_list rest_list
| symbol_list optional_list rest_list """
def p_rest_list(p):
# &rest option in argument list
""" rest_list : REST symbol_list """
def p_optional_list(p):
# &optional option in argument list
""" optional_list : OPTIONAL symbol_list """
def p_symbol_list(p):
""" symbol_list : SYMBOL
| symbol_list SYMBOL """
def p_factor_list(p):
""" factor_list : factor
| factor_list factor"""
def p_factor(p):
""" factor : SYMBOL
| NUMBER
| DECIMAL """
def p_operator(p):
""" operator : PLUS
| MINUS
| TIMES
| DIVIDED
| EQUAL
| GT
| LT
| GEQT
| LEQT """
def p_booleans(p):
""" booleans : T
| NIL"""
def p_error(p):
print("Syntax error!")
file = open('res', 'a')
file.write('Syntax error!\n')
file.close()
parser = yacc.yacc()
'''
print("ENTER '(quit)' TO EXIT")
while True:
try:
s = input("lisp >>> ")
if s == '(quit)':
break
except EOFError:
break
if not s: continue
result = parser.parse(s)
'''
def validate(expr):
return parser.parse(expr)
print("(lambda (x) (* x 5))")
validate("(lambda (x) (* x 5))") # correct
print("(lambda (x) (+ x 5 8 5))")
validate("(lambda (x) (+ x 5 8 5))") # correct
print("(lambda (x &optional y) (+ x y))")
validate("(lambda (x &optional y) (+ x y))") # correct
print("(lambda (x &optional y z) (/ x y z))")
validate("(lambda (x &optional y z) (/ x y z))") # correct
print("(lambda (x &optional y &optional z) (/ x y z))")
validate("(lambda (x &optional y &optional z) (/ x y z))") # incorrect
print("(lambda (x &optional y &rest z) (/ x y z))")
validate("(lambda (x &optional y &rest z) (/ x y z))") # correct
print("(lambda (x &optional y &rest z) (* (+ x 5) 5))")
validate("(lambda (x &optional y &rest z) (* (+ x 5) 5))") # correct
print("(lambda (x) (* (+ (+ x 5) 5) 5 6 6 5))")
validate("(lambda (x) (* (+ (+ x 5) 5) 5 6 6 5))") # correct
print("(lambda (x &rest y) (* (exp (+ x 5) 5)))")
validate("(lambda (x &rest y) (* (exp (+ x 5) 5)))") # correct
print("(lambda (&optional y) (if (y) (write y) (exp 2)))")
validate("(lambda (&optional y) (if (y) (write y) (exp 2)))") # correct