def typedIds(kind, l): """ Parses typedIds(l) = ident «write(ident)» {"," «write(', ')» ident «write(ident)»} ":" «write(': ')» type(l). Updates current scope of symbol table Assumes kind is Var or Ref and applies it to all identifiers Reports an error if an identifier is already defined in the current scope """ if SC.sym == IDENT: write(SC.val) tid = [SC.val] getSym() else: mark("identifier expected") tid = [] while SC.sym == COMMA: write(', ') getSym() if SC.sym == IDENT: write(SC.val) tid.append(SC.val) getSym() else: mark('identifier expected') if SC.sym == COLON: write(': ') getSym() tp = typ(l).tp if tp != None: for i in tid: newObj(i, kind(tp)) else: mark("':' expected")
def typedIds(kind): """ Parses typedIds = ident {"," ident} ":" type. Updates current scope of symbol table Assumes kind is Var or Ref and applies it to all identifiers Reports an error if an identifier is already defined in the current scope """ tid = [SC.val]; getSym() while SC.sym == COMMA: getSym() if SC.sym == IDENT: tid.append(SC.val); getSym() else: mark('identifier expected') if SC.sym == COLON: getSym(); tp = typ().tp for i in tid: newObj(i, kind(tp)) else: mark("':' expected")
def typedIds(kind): """ Parses typedIds = ident {"," ident} ":" type. Updates current scope of symbol table Assumes kind is Var or Ref and applies it to all identifiers Reports an error if an identifier is already defined in the current scope """ if SC.sym == IDENT: tid = [SC.val] getSym() else: mark("identifier expected") tid = [] while SC.sym == COMMA: # attribute write(', ') writeHtml(', ') # getSym() if SC.sym == IDENT: # attribute write(SC.val) writeHtml(SC.val) # tid.append(SC.val) getSym() else: mark('identifier expected') if SC.sym == COLON: # attribute write(': ') writeHtml(': ') # getSym() tp = typ().tp if tp != None: for i in tid: newObj(i, kind(tp)) else: mark("':' expected")
def typedIds(kind): """ Parses typedIds = ident {"," ident} ":" type. Updates current scope of symbol table Assumes kind is Var or Ref and applies it to all identifiers Reports an error if an identifier is already defined in the current scope """ tid = [SC.val] getSym() while SC.sym == COMMA: getSym() if SC.sym == IDENT: tid.append(SC.val) getSym() else: mark('identifier expected', 48) if SC.sym == COLON: getSym() tp = typ().tp for i in tid: newObj(i, kind(tp)) else: mark("':' expected", 49)
def program(): """ Parses program = "program" «write('program ')» ident «write(ident)» ";" «write(';')» declarations compoundStatement(1). Generates code if no error is reported """ newObj('boolean', Type(Bool)) Bool.size = 4 newObj('integer', Type(Int)) Int.size = 4 newObj('true', Const(Bool, 1)) newObj('false', Const(Bool, 0)) newObj('read', StdProc([Ref(Int)])) newObj('write', StdProc([Var(Int)])) newObj('writeln', StdProc([])) CG.progStart() if SC.sym == PROGRAM: # write('program ') writeHtml('program ') # getSym() else: mark("'program' expected") ident = SC.val if SC.sym == IDENT: # write(ident) writeHtml(ident, _class='ident') # getSym() else: mark('program name expected') if SC.sym == SEMICOLON: getSym() # write(';') writeln() writeHtml(';') writeHtmlLn() # else: mark('; expected') declarations(CG.genGlobalVars) CG.progEntry(ident) x = compoundStatement(1) return CG.progExit(x)
def declarations(allocVar): """ Parses declarations = {"const" ident "=" expression ";"} {"type" ident "=" type ";"} {"var" typedIds ";"} {"procedure" ident ["(" [["var"] typedIds {";" ["var"] typedIds}] ")"] ";" declarations compoundStatement ";"}. Updates current scope of symbol table. Reports an error if an identifier is already defined in the current scope. For each procedure, code is generated """ global depth if SC.sym not in FIRSTDECL | FOLLOWDECL: getSym() mark("'begin' or declaration expected") while SC.sym not in FIRSTDECL | STRONGSYMS | FOLLOWDECL: getSym() while SC.sym == CONST: # attributes depth += 1 write(indent * depth) write('const') writeln() writeHtml(htmlIndent * depth) writeHtml('const') writeHtmlLn() # getSym() if SC.sym == IDENT: # attributes depth += 1 ident = SC.val write(indent * depth) write(ident) writeHtml(htmlIndent * depth) # integer constant is upright writeHtml(ident) # getSym() if SC.sym == EQ: # attribute write(' = ') writeHtml(' = ') # getSym() else: mark("= expected") x = expression() if type(x) == Const: newObj(ident, x) else: mark('expression not constant') depth -= 1 else: mark("constant name expected") if SC.sym == SEMICOLON: # attributes write(';') writeln() writeHtml(';') writeHtmlLn() # getSym() else: mark("; expected") depth -= 1 while SC.sym == TYPE: # attributes depth += 1 write(indent * depth) write('type') writeln() writeHtml(htmlIndent * depth) writeHtml('type') writeHtmlLn() # getSym() if SC.sym == IDENT: # attributes depth += 1 ident = SC.val write(indent * depth) write(ident) writeHtml(htmlIndent * depth) writeHtml(ident, _class='ident') # getSym() if SC.sym == EQ: # attributes write(' = ') writeHtml(' = ') # getSym() else: mark("= expected") # attributes (emulate stack) old_depth = depth depth += 1 x = typ() depth = old_depth # newObj(ident, x) # x is of type ST.Type if SC.sym == SEMICOLON: # attribute write(';') writeln() writeHtml(';') writeHtmlLn() getSym() # else: mark("; expected") depth -= 1 else: mark("type name expected") depth -= 1 start = len(topScope()) while SC.sym == VAR: # attributes depth += 1 write(indent * depth) write('var') writeln() writeHtml(htmlIndent * depth) writeHtml('var') writeHtmlLn() depth += 1 getSym() write(indent * depth) write(SC.val) writeHtml(htmlIndent * depth) writeHtml(SC.val) # typedIds(Var) if SC.sym == SEMICOLON: # write(';') writeln() writeHtml(';') writeHtmlLn() getSym() # else: mark("; expected") depth -= 2 varsize = allocVar(topScope(), start) while SC.sym == PROCEDURE: # depth += 1 write(indent * depth) write('procedure ') writeHtml(htmlIndent * depth) writeHtml('procedure ') # getSym() if SC.sym == IDENT: # write(SC.val) writeHtml(SC.val) # getSym() else: mark("procedure name expected") ident = SC.val newObj(ident, Proc([])) # entered without parameters sc = topScope() CG.procStart() openScope() # new scope for parameters and body if SC.sym == LPAREN: # write('(') writeHtml('(') # getSym() if SC.sym in {VAR, IDENT}: if SC.sym == VAR: # write('var ') writeHtml('var ') getSym() write(SC.val) writeHtml(SC.val) # typedIds(Ref) else: typedIds(Var) while SC.sym == SEMICOLON: # write('; ') writeHtml('; ') # getSym() if SC.sym == VAR: # write('var ') writeHtml('var ') getSym() write(SC.val) writeHtml(SC.val) # typedIds(Ref) else: # write(SC.val) writeHtml(SC.val) # typedIds(Var) else: mark("formal parameters expected") fp = topScope() sc[-1].par = fp[:] # procedure parameters updated if SC.sym == RPAREN: # write(')') writeHtml(')') # getSym() else: mark(") expected") else: fp = [] parsize = CG.genFormalParams(fp) if SC.sym == SEMICOLON: # write(';') writeln() writeHtml(';') writeHtmlLn() # getSym() else: mark("; expected") depth += 1 localsize = declarations(CG.genLocalVars) CG.genProcEntry(ident, parsize, localsize) x = compoundStatement(depth + 1) CG.genProcExit(x, parsize, localsize) closeScope() # scope for parameters and body closed if SC.sym == SEMICOLON: getSym() else: mark("; expected") depth -= 1 return varsize
def program(): """ Parses program = "program" ident ";" declarations compoundStatement. Generates code if no error is reported """ newObj("boolean", Type(Bool)) Bool.size = 4 newObj("integer", Type(Int)) Int.size = 4 newObj("true", Const(Bool, 1)) newObj("false", Const(Bool, 0)) newObj("read", StdProc([Ref(Int)])) newObj("write", StdProc([Var(Int)])) newObj("writeln", StdProc([])) progStart() if SC.sym == PROGRAM: getSym() else: mark("'program' expected") ident = SC.val if SC.sym == IDENT: getSym() else: mark("program name expected") if SC.sym == SEMICOLON: getSym() else: mark("; expected") declarations(genGlobalVars) progEntry(ident) x = compoundStatement() return progExit(x)
def declarations(allocVar): """ Parses declarations = {"const" ident "=" expression ";"} {"type" ident "=" type ";"} {"var" typedIds ";"} {"procedure" ident ["(" [["var"] typedIds {";" ["var"] typedIds}] ")"] ";" declarations compoundStatement ";"}. Updates current scope of symbol table. Reports an error if an identifier is already defined in the current scope. For each procedure, code is generated """ if SC.sym not in FIRSTDECL | FOLLOWDECL: getSym() mark("declaration expected") while SC.sym not in FIRSTDECL | FOLLOWDECL: getSym() while SC.sym == CONST: getSym() if SC.sym == IDENT: ident = SC.val getSym() if SC.sym == EQ: getSym() else: mark("= expected") x = expression() if type(x) == Const: newObj(ident, x) else: mark("expression not constant") else: mark("constant name expected") if SC.sym == SEMICOLON: getSym() else: mark("; expected") while SC.sym == TYPE: getSym() if SC.sym == IDENT: ident = SC.val getSym() if SC.sym == EQ: getSym() else: mark("= expected") x = typ() newObj(ident, x) # x is of type ST.Type if SC.sym == SEMICOLON: getSym() else: mark("; expected") else: print(SC.sym) mark("type name expected") start = len(topScope()) while SC.sym == VAR: getSym() typedIds(Var) if SC.sym == SEMICOLON: getSym() else: mark("; expected") varsize = allocVar(topScope(), start) while SC.sym == PROCEDURE: getSym() if SC.sym == IDENT: getSym() else: mark("procedure name expected") ident = SC.val newObj(ident, Proc([])) # entered without parameters sc = topScope() procStart() openScope() # new scope for parameters and body if SC.sym == LPAREN: getSym() if SC.sym in {VAR, IDENT}: if SC.sym == VAR: getSym() typedIds(Ref) # , procParams) else: typedIds(Var) # , procParams) while SC.sym == SEMICOLON: getSym() if SC.sym == VAR: getSym() typedIds(Ref) # , procParams) else: typedIds(Var) # , procParams) else: mark("formal parameters expected") fp = topScope() sc[-1].par = fp[:] # procedure parameters updated if SC.sym == RPAREN: getSym() else: mark(") expected") else: fp = [] parsize = genFormalParams(fp) if SC.sym == SEMICOLON: getSym() else: mark("; expected") localsize = declarations(genLocalVars) genProcEntry(ident, parsize, localsize) x = compoundStatement() genProcExit(x, parsize, localsize) closeScope() # scope for parameters and body closed if SC.sym == SEMICOLON: getSym() else: mark("; expected") return varsize
def declarations(allocVar, l): """ Parses declarations(l) = {"const" «writeln; write(l * indent + 'const')» ident «writeln; write((l + 1) * indent + ident)» "=" «write(' = ')» expression ";" «write(';')»} {"type" «writeln; write(l * indent + 'type')» ident «writeln; write((l + 1) * indent + ident)» "=" «write(' = ')» type(l + 1) ";" «write(';')»} {"var" «writeln; write(l * indent + 'var')» «writeln; write((l + 1) * indent)» typedIds(l + 1) ";" «write(';')»} {"procedure" «writeln; write(l * indent + 'procedure ')» ident «write(ident)» ["(" «write('(')» [["var" «write('var ')»] typedIds(l) {";" «write('; ')» ["var" «write('var ')»] typedIds(l)}] ")" «write(')')»] ";" «write(";")» declarations(l + 1) compoundStatement(l + 1) ";"}. Updates current scope of symbol table. Reports an error if an identifier is already defined in the current scope. For each procedure, code is generated """ if SC.sym not in FIRSTDECL | FOLLOWDECL: getSym() mark("'begin' or declaration expected") while SC.sym not in FIRSTDECL | STRONGSYMS | FOLLOWDECL: getSym() while SC.sym == CONST: writeln() write(l * indent + 'const') getSym() if SC.sym == IDENT: writeln() write((l + 1) * indent + SC.val) ident = SC.val getSym() if SC.sym == EQ: write(' = ') getSym() else: mark("= expected") x = expression() if type(x) == Const: newObj(ident, x) else: mark('expression not constant') else: mark("constant name expected") if SC.sym == SEMICOLON: write(';') getSym() else: mark("; expected") while SC.sym == TYPE: writeln() write(l * indent + 'type') getSym() if SC.sym == IDENT: writeln() write((l + 1) * indent + ident) ident = SC.val getSym() if SC.sym == EQ: write(' = ') getSym() else: mark("= expected") x = typ(l + 1) newObj(ident, x) # x is of type ST.Type if SC.sym == SEMICOLON: write(';') getSym() else: mark("; expected") else: mark("type name expected") start = len(topScope()) while SC.sym == VAR: writeln() write(l * indent + 'var') getSym() writeln() write((l + 1) * indent) typedIds(Var, l + 1) if SC.sym == SEMICOLON: write(';') getSym() else: mark("; expected") varsize = allocVar(topScope(), start) while SC.sym == PROCEDURE: writeln() write(l * indent + 'procedure ') getSym() if SC.sym == IDENT: write(SC.val) getSym() else: mark("procedure name expected") ident = SC.val newObj(ident, Proc([])) # entered without parameters sc = topScope() CG.procStart() openScope() # new scope for parameters and body if SC.sym == LPAREN: write('(') getSym() if SC.sym in {VAR, IDENT}: if SC.sym == VAR: write('var ') getSym() typedIds(Ref, l) else: typedIds(Var, l) while SC.sym == SEMICOLON: write('; ') getSym() if SC.sym == VAR: write('var ') getSym() typedIds(Ref, l) else: typedIds(Var, l) else: mark("formal parameters expected") fp = topScope() sc[-1].par = fp[:] # procedure parameters updated if SC.sym == RPAREN: write(')') getSym() else: mark(") expected") else: fp = [] parsize = CG.genFormalParams(fp) if SC.sym == SEMICOLON: write(';') getSym() else: mark("; expected") localsize = declarations(CG.genLocalVars, l + 1) CG.genProcEntry(ident, parsize, localsize) x = compoundStatement(l + 1) CG.genProcExit(x, parsize, localsize) closeScope() # scope for parameters and body closed if SC.sym == SEMICOLON: write(';') getSym() else: mark("; expected") return varsize
def program(): """ Parses program = "program" ident ";" declarations compoundStatement. Generates code if no error is reported """ newObj('boolean', Type(Bool)) Bool.size = 8 # 64 bit sizes newObj('integer', Type(Int)) Int.size = 8 newObj('true', Const(Bool, 1)) newObj('false', Const(Bool, 0)) newObj('read', StdProc([Ref(Int)])) newObj('write', StdProc([Var(Int)])) newObj('writeln', StdProc([])) progStart() if SC.sym == PROGRAM: getSym() else: mark("'program' expected", 64) ident = SC.val if SC.sym == IDENT: getSym() else: mark('program name expected', 65) if SC.sym == SEMICOLON: getSym() else: mark('; expected', 66) declarations(genGlobalVars) progEntry(ident) x = compoundStatement() return progExit(x)
def declarations(allocVar): """ Parses declarations = {"const" ident "=" expression ";"} {"type" ident "=" type ";"} {"var" typedIds ";"} {"procedure" ident ["(" [["var"] typedIds {";" ["var"] typedIds}] ")"] ";" declarations compoundStatement ";"}. Updates current scope of symbol table. Reports an error if an identifier is already defined in the current scope. For each procedure, code is generated """ if SC.sym not in FIRSTDECL | FOLLOWDECL: getSym() mark("declaration expected", 50) while SC.sym not in FIRSTDECL | FOLLOWDECL: getSym() while SC.sym == CONST: getSym() if SC.sym == IDENT: ident = SC.val getSym() if SC.sym == EQ: getSym() else: mark("= expected", 51) x = expression() if type(x) == Const: newObj(ident, x) else: mark('expression not constant', 52) else: mark("constant name expected", 53) if SC.sym == SEMICOLON: getSym() else: mark("; expected", 54) while SC.sym == TYPE: getSym() if SC.sym == IDENT: ident = SC.val getSym() if SC.sym == EQ: getSym() else: mark("= expected", 55) x = typ() newObj(ident, x) # x is of type ST.Type if SC.sym == SEMICOLON: getSym() else: mark("; expected", 56) else: mark("type name expected", 57) start = len(topScope()) while SC.sym == VAR: getSym() typedIds(Var) if SC.sym == SEMICOLON: getSym() else: mark("; expected", 58) varsize = allocVar(topScope(), start) while SC.sym == PROCEDURE: getSym() if SC.sym == IDENT: getSym() else: mark("procedure name expected", 59) ident = SC.val newObj(ident, Proc([])) # entered without parameters sc = topScope() procStart() openScope() # new scope for parameters and body if SC.sym == LPAREN: getSym() if SC.sym in {VAR, IDENT}: if SC.sym == VAR: getSym() typedIds(Ref) #, procParams) else: typedIds(Var) #, procParams) while SC.sym == SEMICOLON: getSym() if SC.sym == VAR: getSym() typedIds(Ref) #, procParams) else: typedIds(Var) #, procParams) else: mark("formal parameters expected", 60) fp = topScope() sc[-1].par = fp[:] # procedure parameters updated if SC.sym == RPAREN: getSym() else: mark(") expected", 61) else: fp = [] parsize = genFormalParams(fp) if SC.sym == SEMICOLON: getSym() else: mark("; expected", 62) # PROCEDURE CALL localsize = declarations(genLocalVars) genProcEntry(ident, parsize, localsize) x = compoundStatement() genProcExit(x, parsize, localsize) closeScope() # scope for parameters and body closed if SC.sym == SEMICOLON: getSym() else: mark("; expected", 63) return varsize