def declarations(allocVar): while SC.sym == CONST: getSym() if SC.sym == IDENT: ident = SC.val; getSym() else: mark("constant name expected") if SC.sym == EQ: getSym() else: mark("= expected") x = expression() if type(x) == Const: newDecl(ident, x) else: mark('expression not constant') while SC.sym == TYPE: getSym() if SC.sym == IDENT: ident = SC.val; getSym() else: mark("type name expected") if SC.sym == EQ: getSym() else: mark("= expected") x = typ(); newDecl(ident, x) # x is of type ST.Type start = len(topScope()) while SC.sym == VAR: getSym(); typedIds() var = allocVar(topScope(), start) while SC.sym == PROCEDURE: getSym() if SC.sym == LPAREN: getSym() if SC.sym == IDENT: r = SC.val; getSym() else: mark("identifier expected") if SC.sym == COLON: getSym() else: mark("':' expected") tp = typ().val if SC.sym == RPAREN: getSym() else: mark(") expected") else: r = None if SC.sym == IDENT: ident = SC.val; getSym() else: mark("procedure name expected") newDecl(ident, Proc([], [])) # entered without parameters sc = topScope(); openScope() # new scope for parameters and body if r: newDecl(r, Var(tp)) if SC.sym == LPAREN: getSym() else: mark("( expected") if SC.sym == IDENT: typedIds() fp = topScope() if SC.sym == RPAREN: getSym() else: mark(") expected") d = len(fp) if SC.sym == RARROW: getSym() if SC.sym == LPAREN: getSym() else: mark('( expected') typedIds() if SC.sym == RPAREN: getSym() else: mark(') expected') sc[-1].par, sc[-1].res = fp[:d], fp[d:] # procedure parameters updated para = CG.genProcStart(ident, fp[:d], fp[d:]) body(ident, para); closeScope() # scope for parameters and body closed return var
def typ(): """ Parses type = ident | "array" "[" expression ".." expression "]" "of" type | "record" typedIds {";" typedIds} "end". Returns a type descriptor """ if SC.sym not in FIRSTTYPE: getSym() mark("type expected", 37) while SC.sym not in FIRSTTYPE | FOLLOWTYPE | STRONGSYMS: getSym() if SC.sym == IDENT: ident = SC.val x = find(ident) getSym() if type(x) == Type: x = Type(x.tp) else: mark('not a type', 38) elif SC.sym == ARRAY: getSym() if SC.sym == LBRAK: getSym() else: mark("'[' expected", 39) x = expression() if type(x) != Const or x.val < 0: mark('bad lower bound', 40) if SC.sym == PERIOD: getSym() else: mark("'.' expected", 41) if SC.sym == PERIOD: getSym() else: mark("'.' expected", 42) y = expression() if type(y) != Const or y.val < x.val: mark('bad upper bound', 43) if SC.sym == RBRAK: getSym() else: mark("']' expected", 44) if SC.sym == OF: getSym() else: mark("'of' expected", 45) z = typ().tp l = y.val - x.val + 1 x = Type(genArray(Array(z, x.val, l))) elif SC.sym == RECORD: getSym() openScope() typedIds(Var) while SC.sym == SEMICOLON: getSym() typedIds(Var) if SC.sym == END: getSym() else: mark("'end' expected", 46) r = topScope() closeScope() x = Type(genRec(Record(r))) else: mark("type expected", 47) x = Type(None) return x
def typ(): if SC.sym not in FIRSTTYPE: getSym() mark("type expected") while SC.sym not in FIRSTTYPE | STRONGSYMS | FOLLOWTYPE: getSym() if SC.sym == IDENT: ident = SC.val x = find(ident) getSym() if type(x) == Type: x = Type(x.val) else: mark('not a type') x = Type(None) elif SC.sym == ARRAY: getSym() if SC.sym == LBRAK: getSym() else: mark("'[' expected") x = expression() if SC.sym == PERIOD: getSym() else: mark("'.' expected") if SC.sym == PERIOD: getSym() else: mark("'.' expected") y = expression() if SC.sym == RBRAK: getSym() else: mark("']' expected") if SC.sym == OF: getSym() else: mark("'of' expected") z = typ().val if type(x) != Const or x.val < 0: mark('bad lower bound') x = Type(None) elif type(y) != Const or y.val < x.val: mark('bad upper bound') x = Type(None) else: x = Type(CG.genArray(Array(z, x.val, y.val - x.val + 1))) elif SC.sym == RECORD: getSym() openScope() typedIds(Var) while SC.sym == SEMICOLON: getSym() typedIds(Var) if SC.sym == END: getSym() else: mark("'end' expected") r = topScope() closeScope() x = Type(CG.genRec(Record(r))) else: x = Type(None) return x
def program(): newDecl('boolean', Type(CG.genBool(Bool))) newDecl('integer', Type(CG.genInt(Int))) newDecl('true', Const(Bool, 1)) newDecl('false', Const(Bool, 0)) newDecl('read', StdProc([], [Var(Int)])) newDecl('write', StdProc([Var(Int)], [])) newDecl('writeln', StdProc([], [])) CG.genProgStart() declarations(CG.genGlobalVars) if SC.sym == PROGRAM: getSym() else: mark("'program' expected") ident = SC.val if SC.sym == IDENT: getSym() else: mark('program name expected') openScope(); CG.genProgEntry(ident); x = body(ident, 0) closeScope(); x = CG.genProgExit(x) return x
def typ(): """ Parses type = ident | "array" "[" expression ".." expression "]" "of" type | "record" typedIds {";" typedIds} "end". Returns a type descriptor """ if SC.sym not in FIRSTTYPE: getSym(); mark("type expected") while SC.sym not in FIRSTTYPE | FOLLOWTYPE |STRONGSYMS: getSym() if SC.sym == IDENT: ident = SC.val; x = find(ident); getSym() if type(x) == Type: x = Type(x.tp) else: mark('not a type') elif SC.sym == ARRAY: getSym() if SC.sym == LBRAK: getSym() else: mark("'[' expected") x = expression() if type(x) != Const or x.val < 0: mark('bad lower bound') if SC.sym == PERIOD: getSym() else: mark("'.' expected") if SC.sym == PERIOD: getSym() else: mark("'.' expected") y = expression() if type(y) != Const or y.val < x.val: mark('bad upper bound') if SC.sym == RBRAK: getSym() else: mark("']' expected") if SC.sym == OF: getSym() else: mark("'of' expected") z = typ().tp; l = y.val - x.val + 1 x = Type(genArray(Array(z, x.val, l))) elif SC.sym == RECORD: getSym(); openScope(); typedIds(Var) while SC.sym == SEMICOLON: getSym(); typedIds(Var) if SC.sym == END: getSym() else: mark("'end' expected") r = topScope(); closeScope() x = Type(genRec(Record(r))) else: mark("type expected"); x = Type(None) return x
def typ(): if SC.sym == IDENT: ident = SC.val; x = find(ident) if type(x) == Type: x = Type(x.val); getSym() else: mark('type identifier expected') elif SC.sym == LBRAK: getSym(); x = expression() if SC.sym == DOTDOT: getSym() else: mark("'..' expected") y = expression() if SC.sym == RBRAK: getSym() else: mark("']' expected") if SC.sym == RARROW: getSym() else: mark("'→' expected") z = typ().val; if type(x) != Const or x.val < 0: mark('bad lower bound') elif type(y) != Const or y.val < x.val: mark('bad upper bound') else: x = Type(CG.genArray(Array(z, x.val, y.val - x.val + 1))) elif SC.sym == LPAREN: getSym(); openScope(); typedIds() if SC.sym == RPAREN: getSym() else: mark("')' expected") r = topScope(); closeScope() x = Type(CG.genRec(Record(r))) elif SC.sym == FULLPAREN: pass elif SC.sym == SET: getSym(); if SC.sym == LBRAK: getSym() else: mark ("'[' expected") x = expression() if SC.sym == DOTDOT: getSym() else: mark("'..' expected") y = expression() if SC.sym == RBRAK: getSym() else: mark("']' expected") if type(x) != Const: mark('bad lower bound') elif type(y) != Const or y.val < x.val: mark('bad upper bound') else: x = Type(CG.genSet(Set(x.val, y.val - x.val + 1))) else: mark('type expected') return x
def declarations(allocVar): 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: getSym() if SC.sym == IDENT: ident = SC.val getSym() if SC.sym == EQ: getSym() else: mark("= expected") x = expression() if type(x) == Const: newDecl(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() newDecl(ident, x) # x is of type ST.Type if SC.sym == SEMICOLON: getSym() else: mark("; expected") else: 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 newDecl(ident, Proc([])) # entered without parameters sc = topScope() CG.genProcStart() 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) else: typedIds(Var) while SC.sym == SEMICOLON: getSym() if SC.sym == VAR: getSym() typedIds(Ref) else: typedIds(Var) 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 = CG.genFormalParams(fp) if SC.sym == SEMICOLON: getSym() else: mark("; expected") localsize = declarations(CG.genLocalVars) CG.genProcEntry(ident, parsize, localsize) x = compoundStatement() CG.genProcExit(x, parsize, localsize) closeScope() # scope for parameters and body closed if SC.sym == SEMICOLON: getSym() else: mark("; expected") return varsize
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 typ(): """ Parses type = ident | "array" "[" expression ".." expression "]" "of" type | "record" typedIds {";" typedIds} "end". Returns a type descriptor """ global depth if SC.sym not in FIRSTTYPE: getSym() mark("type expected") while SC.sym not in FIRSTTYPE | STRONGSYMS | FOLLOWTYPE: getSym() if SC.sym == IDENT: # attribute ident = SC.val write(ident) writeHtml(ident, _class='ident') # x = find(ident) getSym() if type(x) == Type: x = Type(x.tp) else: mark('not a type') x = Type(None) elif SC.sym == ARRAY: depth += 1 # attribute writeln() write(indent * depth) write('array ') writeHtmlLn() writeHtml(htmlIndent * depth) writeHtml('array ') # getSym() if SC.sym == LBRAK: # attribute write('[') writeHtml('[') # getSym() else: mark("'[' expected") x = expression() if SC.sym == PERIOD: # attribute write(' .') writeHtml(' .') # getSym() else: mark("'.' expected") if SC.sym == PERIOD: # attribute write('. ') writeHtml('. ') # getSym() else: mark("'.' expected") y = expression() if SC.sym == RBRAK: # attribute write('] ') writeHtml('] ') # getSym() else: mark("']' expected") if SC.sym == OF: # attribute write('of') writeHtml('of') # getSym() else: mark("'of' expected") z = typ().tp if type(x) != Const or x.val < 0: mark('bad lower bound') x = Type(None) elif type(y) != Const or y.val < x.val: mark('bad upper bound') y = Type(None) else: x = Type(CG.genArray(Array(z, x.val, y.val - x.val + 1))) depth -= 1 elif SC.sym == RECORD: # attributes depth += 1 writeln() write(indent * depth) write('record') writeln() writeHtmlLn() writeHtml(htmlIndent * depth) writeHtml('record') writeHtmlLn() depth += 1 # getSym() # attributes write(indent * depth) write(SC.val) writeHtml(htmlIndent * depth) writeHtml(SC.val) # openScope() typedIds(Var) while SC.sym == SEMICOLON: # attributes write(';') writeln() writeHtml(';') writeHtmlLn() # getSym() # attributes write(indent * depth) write(SC.val) writeHtml(htmlIndent * depth) writeHtml(SC.val) # typedIds(Var) # attributes writeln() writeHtmlLn() depth -= 1 write(indent * depth) writeHtml(htmlIndent * depth) # if SC.sym == END: # attributes write('end') writeHtml('end') # getSym() else: mark("'end' expected") r = topScope() closeScope() x = Type(CG.genRec(Record(r))) depth -= 1 else: x = Type(None) return 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 typ(l): """ Parses type(l) = ident «write(ident)» | "array" «writeln; write((l + 1) * indent + 'array ')» "[" «write('[')» expression ".." «write(' .. ')» expression "]" «write(']')» "of" «write(' of ')» type(l)| "record" «writeln; write((l + 1) * indent + 'record')» typedIds(l) {";" «write(';')» typedIds(l)} "end" «writeln; write((l + 1) * indent + 'end')». Returns a type descriptor """ if SC.sym not in FIRSTTYPE: getSym() mark("type expected") while SC.sym not in FIRSTTYPE | STRONGSYMS | FOLLOWTYPE: getSym() if SC.sym == IDENT: write(SC.val) ident = SC.val x = find(ident) getSym() if type(x) == Type: x = Type(x.tp) else: mark('not a type') x = Type(None) elif SC.sym == ARRAY: writeln() write((l + 1) * indent + 'array ') getSym() if SC.sym == LBRAK: write('[') getSym() else: mark("'[' expected") x = expression() if SC.sym == PERIOD: write(' .') getSym() else: mark("'.' expected") if SC.sym == PERIOD: write('. ') getSym() else: mark("'.' expected") y = expression() if SC.sym == RBRAK: write(']') getSym() else: mark("']' expected") if SC.sym == OF: write(' of ') getSym() else: mark("'of' expected") z = typ(l + 1).tp if type(x) != Const or x.val < 0: mark('bad lower bound') x = Type(None) elif type(y) != Const or y.val < x.val: mark('bad upper bound') y = Type(None) else: x = Type(CG.genArray(Array(z, x.val, y.val - x.val + 1))) elif SC.sym == RECORD: writeln() write((l + 1) * indent + 'record ') writeln() write((l + 2) * indent) getSym() openScope() typedIds(Var, l + 2) while SC.sym == SEMICOLON: write(';') writeln() write((l + 2) * indent) getSym() typedIds(Var, l + 2) if SC.sym == END: writeln() write((l + 1) * indent + 'end') getSym() else: mark("'end' expected") r = topScope() closeScope() x = Type(CG.genRec(Record(r))) else: x = Type(None) return 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