-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patharg.py
162 lines (132 loc) · 5.36 KB
/
arg.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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import re
from error import *
class Arg:
datatype = None
frame = None
value = None
def __init__(self, arg):
""" Extracts values from <argN> XML element
if the parameter is None it will define empty Argument """
if arg == None:
return
if len(arg.attributes) != 1:
err.exit_script(err.lexical_or_syntax)
if "type" not in arg.attributes:
err.exit_script(err.lexical_or_syntax)
self.datatype = arg.attributes["type"].value
if arg.firstChild == None and self.datatype != "string":
err.exit_script(err.lexical_or_syntax)
if self.datatype == "var":
self.frame = arg.firstChild.nodeValue.partition("@")[0]
self.value = arg.firstChild.nodeValue.partition("@")[2]
else:
self.frame = None
if arg.firstChild != None:
self.value = arg.firstChild.nodeValue
if self.datatype == "string":
self.value = self.decode_string()
else:
self.value = ""
def write(self, std):
""" Writes its own value to a specified output stream """
if self.datatype == "nil":
std.write("")
elif self.datatype == "float":
std.write(self.value.hex())
else:
std.write(str(self.value))
def read(self, datatype):
""" Reads a value from stdin with type specified by datatype """
try:
self.datatype = datatype
input_value = input()
except:
if datatype == "int":
self.value = 0
elif datatype == "bool":
self.value = "false"
elif datatype == "string":
self.value = ""
elif datatype == "float":
self.value = 0.0
return
if datatype == "int":
self.value = input_value
if not self.is_valid_int():
self.value = 0
elif datatype == "bool":
if input_value.upper() == "TRUE":
self.value = "true"
else:
self.value = "false"
elif datatype == "string":
self.value = input_value
#if not self.is_valid_string(): # Lexical check shouldn't be needed...
# self.value = ""
elif datatype == "float":
self.value = input_value
if not self.is_valid_float():
self.value = 0.0
def decode_string(self):
""" Converts string's escape sequences into regular characters """
def replace(match):
return chr(int(match.group()[1:]))
regex = re.compile(r"\\[0-9][0-9][0-9]")
return re.sub(regex, replace, self.value)
def is_valid_int(self):
""" Lexically checks whether the value is a valid integer and converts it """
if self.datatype == "int":
if self.value.isdigit() or \
self.value[0] == "+" and self.value[1:].isdigit() or \
self.value[0] == "-" and self.value[1:].isdigit():
self.value = int(self.value)
return True
return False
def is_valid_bool(self):
""" Lexically checks whether the value is a valid bool """
if self.datatype == "bool" and (self.value == "true" or self.value == "false"):
return True
return False
def is_valid_string(self):
""" Lexically checks whether the value is a valid string """
if self.datatype == "string":
pattern = re.compile(r"^([^#\\\\]|(\\\\[0-9][0-9][0-9]))*$")
result = re.match(pattern, self.value)
if result != None:
return True
return False
def is_valid_float(self):
""" Converts hexadecimal float into regular float """
if self.datatype == "float":
self.value = float.fromhex(self.value)
return True
return False
def is_valid_var(self):
""" Lexically checks whether the value is a valid variable name """
if self.datatype == "var" and self.frame == "GF" or self.frame == "TF" or self.frame == "LF":
pattern = re.compile(r"^[a-zA-Z_$&%*!?\-][a-zA-Z0-9_$&%*!?\-]*$")
result = re.match(pattern, self.value)
if result != None:
return True
return False
def is_valid_symb(self):
""" Lexically checks whether the value is a valid symb """
if self.is_valid_var() or self.is_valid_int() or self.is_valid_bool() or self.is_valid_string() or self.is_valid_float():
return True
elif self.datatype == "nil" and self.value == "nil":
return True
return False
def is_valid_label(self):
""" Lexically checks whether the value is a valid label name """
if self.datatype == "label":
pattern = re.compile(r"^[a-zA-Z_$&%*!?\-][a-zA-Z0-9_$&%*!?\-]*$")
result = re.match(pattern, self.value)
if result != None:
return True
return False
def is_valid_type(self):
""" Lexically checks whether the value is a valid type """
if self.datatype == "type":
if self.value == "int" or self.value == "bool" or self.value == "string" or self.value == "float":
return True
return False