-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfunction.py
More file actions
155 lines (125 loc) · 2.89 KB
/
function.py
File metadata and controls
155 lines (125 loc) · 2.89 KB
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
145
146
147
148
149
150
151
152
153
154
155
import ply.lex as lex
import ply.yacc as yacc
#Lexical analysis
# define tokens for the lexer
tokens = (
'NUMBER',
'STRING',
'IDENTIFIER',
'PLUS',
'MINUS',
'TIMES',
'DIVIDE',
'LPAREN',
'RPAREN',
'COLON',
'EQUALS',
'NEWLINE',
'COMMA',
'OPERATOR',
)
# Keywords
keywords = {
'if': 'IF',
'else': 'ELSE',
'while': 'WHILE',
'for': 'FOR',
'def': 'DEF',
'return': 'RETURN',
}
tokens += tuple(keywords.values())
# Regular expression rules for simple tokens
t_PLUS = r'\+'
t_MINUS = r'-'
t_TIMES = r'\*'
t_DIVIDE = r'/'
t_LPAREN = r'\('
t_RPAREN = r'\)'
t_COLON = r':'
t_EQUALS = r'='
t_COMMA = r','
t_OPERATOR = r'==|!=|<=|>=|<|>'
# Ignore spaces and tabs
t_ignore = ' \t'
def t_STRING(t):
r'\"([^\\\"]|\\.)*\"'
return t
def t_NUMBER(t):
r'\d+'
t.value = int(t.value)
return t
def t_IDENTIFIER(t):
r'[a-zA-Z_][a-zA-Z_0-9]*'
t.type = keywords.get(t.value, 'IDENTIFIER')
return t
def t_NEWLINE(t):
r'\n+'
t.lexer.lineno += len(t.value)
return t
# Error handling
def t_error(t):
print(f"Illegal character '{t.value[0]}' at line {t.lineno}")
t.lexer.skip(1)
# Build the lexer
lexer = lex.lex()
#Syntax analysis (parser)
# Precedence rules for arithmetic operators
precedence = (
('left', 'PLUS', 'MINUS'),
('left', 'TIMES', 'DIVIDE'),
)
variables = {}
# Grammar rules
def p_program(p):
'''program : statement
| statement program'''
pass
def p_statement(p):
'''statement : function_def
| if_statement
| expression_statement'''
pass
def p_function_def(p):
'''function_def : DEF IDENTIFIER LPAREN IDENTIFIER RPAREN COLON statement'''
print(f"Function definition: {p[2]} with parameter {p[4]}")
def p_if_statement(p):
'''if_statement : IF expression COLON statement ELSE COLON statement'''
print("If-Else statement detected")
def p_expression_statement(p):
'''expression_statement : expression NEWLINE'''
print(f"Expression: {p[1]}")
def p_expression(p):
'''expression : expression PLUS expression
| expression MINUS expression
| expression TIMES expression
| expression DIVIDE expression
| NUMBER
| IDENTIFIER'''
if len(p) == 2:
p[0] = p[1]
else:
p[0] = (p[2], p[1], p[3])
print(f"Expression: {p[1]} {p[2]} {p[3]}")
def p_error(p):
if p:
print(f"Syntax error at token {p.type} ('{p.value}')")
else:
print("Syntax error at EOF")
# Build the parser
parser = yacc.yacc()
# Input code snippet
input_code = """
def my_function(x):
if x > 10:
return x + 5
else:
return x - 5
"""
# Run the lexer
print("Tokens:")
lexer.input(input_code)
for token in lexer:
print(token)
# Run the parser
print("\nParsing:")
parser.parse(input_code)