import sys
import Lexer
class ParserXML:
"""Parser for Jack programming language to produce an XML representation"""
def __init__(self, file):
[Link] = [Link](file)
[Link] = open(file[0:-5] + ".xml", "w")
[Link]('<?xml version="1.0" encoding="UTF-8"?>\n')
[Link] = None # For storing the current token from the lexer
[Link]() # Initialize the first token
def advance(self):
"""Advances to the next token."""
[Link] = [Link]()
def jackclass(self):
[Link](f"<class>\n")
[Link]('class') # 'class'
[Link]() # className
[Link]('{') # '{'
while [Link] and [Link]['token'] in ['static', 'field']:
[Link]() # classVarDec*
while [Link] and [Link]['token'] in ['constructor', 'function',
'method']:
[Link]() # subroutineDec*
[Link]('}') # '}'
[Link](f"</class>\n")
def classVarDec(self):
[Link](f"<classVarDec>\n")
kind = [Link]['token'] # 'static' or 'field'
[Link](kind)
[Link]() # type
[Link]() # varName
while [Link] and [Link]['token'] == ',':
[Link](',')
[Link]() # varName
[Link](';') # ';'
[Link](f"</classVarDec>\n")
def type(self):
""" Handles types in Jack"""
[Link](f"<type>\n")
if [Link]['token'] in ['int', 'char', 'boolean']:
[Link]([Link]['token']) # 'int', 'char', 'boolean'
else:
[Link]() # className
[Link](f"</type>\n")
def subroutineDec(self):
[Link](f"<subroutineDec>\n")
kind = [Link]['token'] # 'constructor', 'function', 'method'
[Link](kind)
if [Link]['token'] in ['void']:
[Link]('void') # 'void'
else:
[Link]() # type
[Link]() # subroutineName
[Link]('(') # '('
[Link]() # parameterList
[Link](')') # ')'
[Link]() # subroutineBody
[Link](f"</subroutineDec>\n")
def parameterList(self):
[Link](f"<parameterList>\n")
if [Link] and [Link]['token'] in ['int', 'char', 'boolean']:
[Link]() # type
[Link]() # varName
while [Link] and [Link]['token'] == ',':
[Link](',')
[Link]() # type
[Link]() # varName
[Link](f"</parameterList>\n")
def subroutineBody(self):
[Link](f"<subroutineBody>\n")
[Link]('{') # '{'
while [Link] and [Link]['token'] == 'var':
[Link]() # varDec*
[Link]() # statements
[Link]('}') # '}'
[Link](f"</subroutineBody>\n")
def varDec(self):
[Link](f"<varDec>\n")
[Link]('var') # 'var'
[Link]() # type
[Link]() # varName
while [Link] and [Link]['token'] == ',':
[Link](',')
[Link]() # varName
[Link](';') # ';'
[Link](f"</varDec>\n")
def className(self):
[Link](f"<className>")
[Link]([Link]['token']) # identifier
[Link](f"</className>\n")
def subroutineName(self):
[Link](f"<subroutineName>")
[Link]([Link]['token']) # identifier
[Link](f"</subroutineName>\n")
def varName(self):
[Link](f"<varName>")
[Link]([Link]['token']) # identifier
[Link](f"</varName>\n")
def statements(self):
[Link](f"<statements>\n")
while [Link] and [Link]['token'] in ['let', 'if', 'while', 'do',
'return']:
[Link]() # statement*
[Link](f"</statements>\n")
def statement(self):
[Link](f"<statement>\n")
if [Link]['token'] == 'let':
[Link]() # letStatement
elif [Link]['token'] == 'if':
[Link]() # ifStatement
elif [Link]['token'] == 'while':
[Link]() # whileStatement
elif [Link]['token'] == 'do':
[Link]() # doStatement
elif [Link]['token'] == 'return':
[Link]() # returnStatement
[Link](f"</statement>\n")
def letStatement(self):
[Link](f"<letStatement>\n")
[Link]('let') # 'let'
[Link]() # varName
if [Link] and [Link]['token'] == '[':
[Link]('[') # '['
[Link]() # expression
[Link](']') # ']'
[Link]('=') # '='
[Link]() # expression
[Link](';') # ';'
[Link](f"</letStatement>\n")
def ifStatement(self):
[Link](f"<ifStatement>\n")
[Link]('if') # 'if'
[Link]('(') # '('
[Link]() # expression
[Link](')') # ')'
[Link]('{') # '{'
[Link]() # statements
[Link]('}') # '}'
if [Link] and [Link]['token'] == 'else':
[Link]('else') # 'else'
[Link]('{') # '{'
[Link]() # statements
[Link]('}') # '}'
[Link](f"</ifStatement>\n")
def whileStatement(self):
[Link](f"<whileStatement>\n")
[Link]('while') # 'while'
[Link]('(') # '('
[Link]() # expression
[Link](')') # ')'
[Link]('{') # '{'
[Link]() # statements
[Link]('}') # '}'
[Link](f"</whileStatement>\n")
def doStatement(self):
[Link](f"<doStatement>\n")
[Link]('do') # 'do'
[Link]() # subroutineCall
[Link](';') # ';'
[Link](f"</doStatement>\n")
def returnStatement(self):
[Link](f"<returnStatement>\n")
[Link]('return') # 'return'
if [Link] and [Link]['token'] != ';':
[Link]() # expression
[Link](';') # ';'
[Link](f"</returnStatement>\n")
def expression(self):
[Link](f"<expression>\n")
[Link]() # term
while [Link] and [Link]['token'] in ['+', '-', '*', '/', '&', '|',
'<', '>', '=']:
[Link]() # op
[Link]() # term
[Link](f"</expression>\n")
def term(self):
[Link](f"<term>\n")
if [Link]['type'] == 'IntegerConstant':
[Link]([Link]['token']) # integerConstant
elif [Link]['type'] == 'StringConstant':
[Link]([Link]['token']) # stringConstant
elif [Link]['token'] in ['true', 'false', 'null', 'this']:
[Link]() # keywordConstant
elif [Link]['type'] == 'identifier':
[Link]() # varName
if [Link] and [Link]['token'] == '[':
[Link]('[')
[Link]() # expression
[Link](']')
elif [Link] and [Link]['token'] == '.':
[Link]() # subroutineCall
elif [Link] and [Link]['token'] == '(':
[Link]('(')
[Link]() # expression
[Link](')')
elif [Link]['token'] in ['-', '~']:
[Link]() # unaryOp
[Link]() # term
[Link](f"</term>\n")
def subroutineCall(self):
[Link](f"<subroutineCall>\n")
[Link]([Link]['token']) # objectName or subroutineName
if [Link] and [Link]['token'] == '.':
[Link]('.') # Consume the '.'
if [Link] and [Link]['type'] == 'identifier': # This ensures a
method name exists
[Link]([Link]['token']) # Read subroutineName
else:
[Link]([Link]) # This ensures we display the error if no
method is detected
[Link]('(') # Consume '('
[Link]() # Process the arguments
[Link](')') # Consume ')'
[Link](f"</subroutineCall>\n")
def expressionList(self):
[Link](f"<expressionList>\n")
if [Link] and [Link]['type'] in ['IntegerConstant',
'StringConstant', 'identifier', 'keyword']:
[Link]() # expression
while [Link] and [Link]['token'] == ',':
[Link](',')
[Link]() # expression
[Link](f"</expressionList>\n")
def op(self):
[Link](f"<op>\n")
[Link]([Link]['token']) # op
[Link](f"</op>\n")
def unaryOp(self):
[Link](f"<unaryOp>\n")
[Link]([Link]['token']) # unaryOp
[Link](f"</unaryOp>\n")
def KeywordConstant(self):
[Link](f"<keyWordConstant>\n")
[Link]([Link]['token']) # keyword constant (true | false | null
| this)
[Link](f"</keyWordConstant>\n")
def process(self, str):
token = [Link]
print(f"Processing token: {token}") # Ajoutez cette ligne pour déboguer
if token is not None and token['token'] == str:
[Link](f"<{token['type']}>{token['token']}</{token['type']}>\
n")
[Link]() # Move to the next token
else:
[Link](token)
def error(self, token):
if token is None:
print("Syntax error: end of file")
else:
print(f"SyntaxError (line={token['line']}, col={token['col']}):
{token['token']}")
exit()
if __name__ == "__main__":
file = [Link][1]
print('-----debut')
parser = ParserXML(file)
[Link]()
print('-----fin')