-
Notifications
You must be signed in to change notification settings - Fork 0
/
parse.py
executable file
·135 lines (105 loc) · 3.01 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
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
#!/usr/bin/python3
import sys
from typing import TextIO
from lexer import Lexer
from ipp24_parser import Instruction, Parser
from errors import Error
from args import Action, Args, parse_args
from statp import Stats
def main(argv: list[str]) -> Error:
args = parse_args(argv)
match args.action:
case Action.PARSE:
return parse(args, sys.stdin)
# return parse(args, open("testfile.IPPcode24", encoding = "utf-8"))
case Action.HELP:
print_help()
return Error.NONE
case Action.ERR:
print("error:", args.err_msg, file = sys.stderr)
return args.err_code
return Error.NONE
def parse(
args: Args,
input: TextIO = sys.stdin,
output: TextIO = sys.stdout
) -> Error:
"""Parses IPPcode from `input` to xml into `output`"""
# parse the input
lexer = Lexer(input)
parser = Parser(lexer)
insts = parser.parse()
# check for errors while parsing
if parser.err_code != Error.NONE:
print("error:", parser.err_msg, file = sys.stderr)
return parser.err_code
# generate xml into output
make_xml(insts, output)
# print the stats
stats = Stats(insts, lexer)
for s in args.stats:
try:
f = open(s.filename, "w")
except Exception as e:
print("error: failed to open file:", e, file = sys.stderr)
return Error.FILE_WRITE
with f:
stats.print_stats(s.stats, f)
return Error.NONE
def make_xml(insts: list[Instruction], out: TextIO):
"""Serializes the instructions into a xml output"""
# The xml serialization is very simple and in this case using library to do
# it wouldn't be much simpler
# the xml header and program tag
out.write(
"""<?xml version="1.0" encoding="UTF-8"?>
<program language="IPPcode24">
"""
)
# write instrucitons
for (idx, inst) in enumerate(insts):
inst.write_xml(idx + 1, out)
# close the program tag
out.write('</program>\n')
def print_help():
"""Prints help to stdout."""
print(
"""Welcome in help for parser by BonnyAD9.
This script parses IPPcode24 into XML.
Usage:
parse
parses from stdin to stdout
parse [options]
Options:
-h -? --help
prints this help
--stats=<filename>
Outputs the stats to the given file. This must appear before any other
stats parameters.
--loc
stat - number of instructions
--comments
stat - number of lines with comments on them
--labels
stat - number of labels
--jumps
stat - number of jumps
--fwjumps
stat - number of jumps forward
--backjumps
stat - number of jumps backwards
--badjumps
stat - number of jumps to nonexisting label
--prints=<text>
stat - prints the given text
--eol
stat - empty line
"""
)
# ensure that this is executed as program
if __name__ == "__main__":
try:
sys.exit(main(sys.argv))
except Exception as e:
print("error:", e, file = sys.stderr)
sys.exit(Error.OTHER)