Heavily modified and simplified Code-A2 (two pass macro processor in
python) - Removed class, there's individual functions now - No more "self", that's too much work for practical exam - Removed expand_macro function, it was unnecessary - Overall refinement for better understanding - Added comments
This commit is contained in:
parent
48b8af36f9
commit
bdfc8ea1b2
@ -1,89 +1,81 @@
|
|||||||
class MacroProcessor:
|
# Assignment-A2 - Two-pass macro processor code in Python
|
||||||
def __init__(self):
|
|
||||||
self.macro_name_table = {}
|
|
||||||
self.macro_definition_table = {}
|
|
||||||
self.mdt_index = 0
|
|
||||||
|
|
||||||
def process_pass1(self, source_code):
|
# BEGINNING OF CODE
|
||||||
inside_macro = False
|
# Required databases
|
||||||
current_macro_name = None
|
macro_definition_table = {} # Storing all macro definitions with their names
|
||||||
macro_definition = []
|
macro_name_table = {} # Storing macro names and their index
|
||||||
|
##########################################################################
|
||||||
|
def process_pass1(source_code):
|
||||||
|
mdt_index = 0
|
||||||
|
macro_definition = []
|
||||||
|
current_macro_name = None
|
||||||
|
inside_macro = False
|
||||||
|
|
||||||
for line in source_code:
|
for line in source_code:
|
||||||
tokens = line.strip().split()
|
tokens = line.strip().split() # store each word of the line of source code
|
||||||
|
|
||||||
if not tokens:
|
if (not tokens): # skips blank lines
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if tokens[0] == 'MACRO':
|
if (tokens[0] == 'MACRO'): # beginning of macro definition
|
||||||
inside_macro = True
|
inside_macro = True
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if inside_macro and tokens[0] == 'MEND':
|
if (inside_macro == True and tokens[0] == 'MEND'): # if end of macro is reached
|
||||||
inside_macro = False
|
inside_macro = False
|
||||||
self.macro_definition_table[current_macro_name] = macro_definition[:]
|
macro_definition_table[current_macro_name] = macro_definition[:]
|
||||||
self.macro_name_table[current_macro_name] = self.mdt_index
|
macro_name_table[current_macro_name] = mdt_index
|
||||||
self.mdt_index += len(macro_definition)
|
mdt_index += len(macro_definition)
|
||||||
macro_definition = []
|
macro_definition = []
|
||||||
current_macro_name = None
|
current_macro_name = None
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if inside_macro:
|
if (inside_macro == True): # processing contents of macro
|
||||||
if not current_macro_name:
|
if (not current_macro_name):
|
||||||
current_macro_name = tokens[0]
|
current_macro_name = tokens[0]
|
||||||
macro_definition.append(line.strip())
|
macro_definition.append(line.strip())
|
||||||
else:
|
##########################################################################
|
||||||
pass
|
def process_pass2(source_code):
|
||||||
|
output = []
|
||||||
|
inside_macro = False
|
||||||
|
|
||||||
def process_pass2(self, source_code):
|
for line in source_code:
|
||||||
output = []
|
tokens = line.strip().split()
|
||||||
inside_macro = False
|
|
||||||
|
|
||||||
for line in source_code:
|
if (not tokens or tokens[0] == 'MACRO'): # skipping spaces, MACRO and MEND keywords
|
||||||
tokens = line.strip().split()
|
inside_macro = True
|
||||||
|
continue
|
||||||
|
elif (tokens[0] == 'MEND'):
|
||||||
|
inside_macro = False
|
||||||
|
continue
|
||||||
|
|
||||||
if not tokens:
|
if inside_macro:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if tokens[0] == 'MACRO':
|
macro_name = tokens[0]
|
||||||
inside_macro = True
|
if macro_name in macro_name_table: # expand macro from source code
|
||||||
continue
|
args = tokens[1:]
|
||||||
elif tokens[0] == 'MEND':
|
macro_def = macro_definition_table[macro_name]
|
||||||
inside_macro = False
|
for expanded_line in macro_def:
|
||||||
continue
|
for i, arg in enumerate(args):
|
||||||
|
expanded_line = expanded_line.replace(f"&ARG{i+1}", arg)
|
||||||
|
output.append(expanded_line)
|
||||||
|
else: # append line if not a macro
|
||||||
|
output.append(line.strip())
|
||||||
|
|
||||||
if inside_macro:
|
return output
|
||||||
continue
|
##########################################################################
|
||||||
|
def display():
|
||||||
macro_name = tokens[0]
|
print("Macro Name Table (MNT):")
|
||||||
if macro_name in self.macro_name_table:
|
for name, index in macro_name_table.items():
|
||||||
macro_def = self.macro_definition_table[macro_name]
|
print(f"Macro Name: {name} | Index: {index}")
|
||||||
args = tokens[1:]
|
|
||||||
output.extend(self.expand_macro(macro_def, args))
|
|
||||||
else:
|
|
||||||
output.append(line.strip())
|
|
||||||
|
|
||||||
return output
|
|
||||||
|
|
||||||
def expand_macro(self, macro_def, args):
|
|
||||||
expanded_lines = []
|
|
||||||
for line in macro_def:
|
|
||||||
for i, arg in enumerate(args):
|
|
||||||
line = line.replace(f"&ARG{i+1}", arg)
|
|
||||||
expanded_lines.append(line)
|
|
||||||
return expanded_lines
|
|
||||||
|
|
||||||
def display_tables(self):
|
|
||||||
print("Macro Name Table (MNT):")
|
|
||||||
for name, index in self.macro_name_table.items():
|
|
||||||
print(f"Macro Name: {name}, MDT Index: {index}")
|
|
||||||
|
|
||||||
print("\nMacro Definition Table (MDT):")
|
|
||||||
for name, definition in self.macro_definition_table.items():
|
|
||||||
print(f"Macro Name: {name}")
|
|
||||||
for line in definition:
|
|
||||||
print(f"\t{line}")
|
|
||||||
|
|
||||||
|
print("Macro Definition Table (MDT):")
|
||||||
|
for name, definition in macro_definition_table.items():
|
||||||
|
print(f"Macro: {name}")
|
||||||
|
for line in definition:
|
||||||
|
print(f"\t{line}")
|
||||||
|
##########################################################################
|
||||||
source_code = [
|
source_code = [
|
||||||
"MACRO",
|
"MACRO",
|
||||||
"INCR &ARG1",
|
"INCR &ARG1",
|
||||||
@ -96,16 +88,13 @@ source_code = [
|
|||||||
"START",
|
"START",
|
||||||
"INCR A",
|
"INCR A",
|
||||||
"DECR B",
|
"DECR B",
|
||||||
"END",
|
"END"
|
||||||
]
|
]
|
||||||
|
##########################################################################
|
||||||
macro_processor = MacroProcessor()
|
process_pass1(source_code)
|
||||||
|
display()
|
||||||
macro_processor.process_pass1(source_code)
|
print("PASS 2:")
|
||||||
macro_processor.display_tables()
|
expanded_code = process_pass2(source_code)
|
||||||
|
for i in expanded_code:
|
||||||
expanded_code = macro_processor.process_pass2(source_code)
|
print(i)
|
||||||
|
# END OF CODE
|
||||||
print("\nExpanded Source Code (Pass 2):")
|
|
||||||
for line in expanded_code:
|
|
||||||
print(line)
|
|
||||||
|
Loading…
Reference in New Issue
Block a user