promote 样例代码的python code:
VariableSymbol.py
- from Symbol import Symbol
- class VariableSymbol( Symbol ):
- def __init__( self,name, type) :
- super(VariableSymbol,self).__init__(name, type)
Type.py
- from Scope import abstract
- class Type(object) :
-
- #def __init__(self):
- # if self.__class__ is Scope:
- # abstract()
-
- #public String getName();
- def getName(self):
- abstract()
-
- #public int getTypeIndex();
- def getTypeIndex(self):
- abstract()
SymbolTable.py
- from CymbolListener import CymbolListener
- from BuiltInTypeSymbol import BuiltInTypeSymbol
- from GlobalScope import GlobalScope
- class SymbolTable(object):
- # arithmetic types defined in order from narrowest to widest
- #public static final int tUSER = 0; // user-defined type (struct)
- tUSER = 0
- #public static final int tBOOLEAN = 1;
- tBOOLEAN = 1
- tCHAR = 2
- tINT = 3
- tFLOAT = 4
- tVOID = 5
- #public static final BuiltInTypeSymbol _boolean =
- # new BuiltInTypeSymbol("boolean", tBOOLEAN);
- print 'liu: now init buildin type'
- _boolean = BuiltInTypeSymbol("boolean", tBOOLEAN)
- _char = BuiltInTypeSymbol("char", tCHAR)
- _int = BuiltInTypeSymbol("int", tINT)
- _float = BuiltInTypeSymbol("float", tFLOAT)
- _void = BuiltInTypeSymbol("void", tVOID)
- #public CymbolListener listener =
- # new CymbolListener() {
- # public void info(String msg) { System.out.println(msg); }
- # public void error(String msg) { System.err.println(msg); }
- # };
-
- #listener = CymbolListener() # liunote move to __init__
- #/** arithmetic types defined in order from narrowest to widest */
- #public static final Type[] indexToType = {
- # // 0, 1, 2, 3, 4, 5
- indexToType = [ None, _boolean, _char, _int, _float, _void ]
-
- #/** Map t1 op t2 to result type (_void implies illegal) */
- #public static final Type[][] arithmeticResultType = new Type[][] {
- # /* struct boolean char int float, void */
- # /*struct*/ {_void, _void, _void, _void, _void, _void},
- # /*boolean*/ {_void, _void, _void, _void, _void, _void},
- # /*char*/ {_void, _void, _char, _int, _float, _void},
- # /*int*/ {_void, _void, _int, _int, _float, _void},
- # /*float*/ {_void, _void, _float, _float, _float, _void},
- # /*void*/ {_void, _void, _void, _void, _void, _void}
- #};
-
- # liunote math calc type change !!!
- arithmeticResultType = [
- [_void, _void, _void, _void, _void, _void ],
- [_void, _void, _void, _void, _void, _void ],
- [_void, _void, _char, _int, _float, _void ],
- [_void, _void, _int, _int, _float, _void ],
- [_void, _void, _float, _float, _float, _void ],
- [_void, _void, _void, _void, _void, _void ]
- ]
- #public static final Type[][] relationalResultType = new Type[][] {
- # /* struct boolean char int float, void */
- # /*struct*/ {_void, _void, _void, _void, _void, _void},
- # /*boolean*/ {_void, _void, _void, _void, _void, _void},
- # /*char*/ {_void, _void, _boolean, _boolean, _boolean, _void},
- # /*int*/ {_void, _void, _boolean, _boolean, _boolean, _void},
- # /*float*/ {_void, _void, _boolean, _boolean, _boolean, _void},
- # /*void*/ {_void, _void, _void, _void, _void, _void}
- #};
-
- # liunote relation calc type change !!!
- relationalResultType = [
- [ _void, _void, _void, _void, _void, _void ],
- [ _void, _void, _void, _void, _void, _void ],
- [ _void, _void, _boolean, _boolean, _boolean, _void ],
- [ _void, _void, _boolean, _boolean, _boolean, _void ],
- [ _void, _void, _boolean, _boolean, _boolean, _void ],
- [ _void, _void, _void, _void, _void, _void ]
- ]
- #public static final Type[][] equalityResultType = new Type[][] {
- # /* struct boolean char int float, void */
- # /*struct*/ {_void, _void, _void, _void, _void, _void},
- # /*boolean*/ {_void, _boolean, _void, _void, _void, _void},
- # /*char*/ {_void, _void, _boolean, _boolean, _boolean, _void},
- # /*int*/ {_void, _void, _boolean, _boolean, _boolean, _void},
- # /*float*/ {_void, _void, _boolean, _boolean, _boolean, _void},
- # /*void*/ {_void, _void, _void, _void, _void, _void}
- #};
- equalityResultType = [
- [ _void, _void, _void, _void, _void, _void ],
- [ _void, _boolean, _void, _void, _void, _void ],
- [ _void, _void, _boolean, _boolean, _boolean, _void ],
- [ _void, _void, _boolean, _boolean, _boolean, _void ],
- [ _void, _void, _boolean, _boolean, _boolean, _void ],
- [ _void, _void, _void, _void, _void, _void ]
- ]
-
- #/** Indicate whether a type needs a promotion to a wider type.
- # * If not null, implies promotion required. Null does NOT imply
- # * error--it implies no promotion. This works for
- # * arithmetic, equality, and relational operators in Cymbol.
- # */
- #public static final Type[][] promoteFromTo = new Type[][] {
- # /* struct boolean char int float, void (liunote formal is colum)*/
- # /*struct*/ {null, null, null, null, null, null},
- # /*boolean*/ {null, null, null, null, null, null},
- # /*char*/ {null, null, null, _int, _float, null},
- # /*int*/ {null, null, null, null, _float, null},
- # /*float*/ {null, null, null, null, null, null},
- # /*void*/ {null, null, null, null, null, null}
- #};
-
- promoteFromTo = [
- [ None, None, None, None, None, None ],
- [ None, None, None, None, None, None ],
- [ None, None, None, _int, _float, None ],
- [ None, None, None, None, _float, None ],
- [ None, None, None, None, None, None ],
- [ None, None, None, None, None, None ]
- ]
- #GlobalScope globals = new GlobalScope();
- #public SymbolTable() { initTypeSystem(); }
-
- #protected void initTypeSystem() {
- # for (Type t : indexToType) {
- # if ( t!=null ) globals.define((BuiltInTypeSymbol)t);
- # }
- #}
- def initTypeSystem(self):
- for t in SymbolTable.indexToType:
- if t != None : self.globals.define(t)
- def __init__(self):
- self.listener = CymbolListener()
- self.globals = GlobalScope()
- self.initTypeSystem()
- #public Type getResultType(Type[][] typeTable, CymbolAST a, CymbolAST b) {
- # int ta = a.evalType.getTypeIndex(); // type index of left operand
- # int tb = b.evalType.getTypeIndex(); // type index of right operand
- # Type result = typeTable[ta][tb]; // operation result type
- # // promote left to right or right to left?
- # a.promoteToType = promoteFromTo[ta][result.getTypeIndex()];
- # b.promoteToType = promoteFromTo[tb][result.getTypeIndex()];
- # return result;
- #}
-
- def getResultType(self,typeTable, a, b) :
- ta = a.evalType.getTypeIndex() # type index of left operand liunote evalType => int a (a+1.1)'evalType is float!!!
- tb = b.evalType.getTypeIndex() # type index of right operand
- result = typeTable[ta][tb] # operation result type
-
- # promote left to right or right to left?
- a.promoteToType = SymbolTable.promoteFromTo[ta][result.getTypeIndex()]
- b.promoteToType = SymbolTable.promoteFromTo[tb][result.getTypeIndex()]
- return result
- #public Type bop(CymbolAST a, CymbolAST b) {
- # return getResultType(arithmeticResultType, a, b);
- #}
- def bop( self,a, b) :
- return self.getResultType(SymbolTable.arithmeticResultType, a, b) # liunote call myslef method ,param need't self
-
- #public Type relop(CymbolAST a, CymbolAST b) {
- # return getResultType(relationalResultType, a, b);
- #}
- def relop(self, a, b) :
- return self.getResultType(SymbolTable.relationalResultType, a, b)
-
- #public Type eqop(CymbolAST a, CymbolAST b) {
- # return getResultType(equalityResultType, a, b);
- #}
- def eqop(self, a, b) :
- return getResultType(SymbolTable.equalityResultType, a, b)
-
- #public Type uminus(CymbolAST a) { return a.evalType; }
- def uminus(self,a): return a.evalType
- #public Type unot(CymbolAST a) { return _boolean; }
- def unot(self, a): return _boolean
- #public Type arrayIndex(CymbolAST id, CymbolAST index) {
- # Symbol s = id.scope.resolve(id.getText()); // resolve variable
- # VariableSymbol vs = (VariableSymbol)s;
- # id.symbol = vs; // annotate AST
- # Type t = ((ArrayType)vs.type).elementType; // get element type
- # int texpr = index.evalType.getTypeIndex();
- # index.promoteToType = promoteFromTo[texpr][tINT]; // promote index?
- # return t;
- #}
- #arrayRef returns [type] //[Type type]
- #: ^(INDEX ID expr)
- # {
- # $type = self.symtab.arrayIndex($ID, $expr.start);
- # $start.evalType = $type;
- # }
- #;
- def arrayIndex(self,id, index) :
- s = id.scope.resolve(id.getText()) # resolve variable # liunote return self.token.text
- vs = s; # liunote VariableSymbol ???
- id.symbol = vs; # annotate AST
- #t = ((ArrayType)vs.type).elementType # get element type
- #type ID '[]' ('=' expression)? ';' -> ^(VAR_DECL ^('[]' type) ID expression?)
- t = (vs.type).elementType # liunote vs.type dont cast to (ArrayType) ???
-
- texpr = index.evalType.getTypeIndex() # liunote index node get it's evalType [2-1] => _int type
- index.promoteToType = SymbolTable.promoteFromTo[texpr][SymbolTable.tINT]; # promote index?
- return t;
- #/** For g('q',10), promote 'q' to int, 10 to float
- # * Given int g(int x, float y) {...} */
- #public Type call(CymbolAST id, List args) {
- # Symbol s = id.scope.resolve(id.getText());
- # MethodSymbol ms = (MethodSymbol)s;
- # id.symbol = ms;
- # int i=0;
- # for (Symbol a : ms.orderedArgs.values() ) { // for each arg
- # CymbolAST argAST = (CymbolAST)args.get(i++);
- # // get argument expression type and expected type
- # Type actualArgType = argAST.evalType;
- # Type formalArgType = ((VariableSymbol)a).type;
- # int targ = actualArgType.getTypeIndex();
- # int tformal = formalArgType.getTypeIndex();
- # // do we need to promote argument type to defined type?
- # argAST.promoteToType = promoteFromTo[targ][tformal];
- # }
- # return ms.type;
- #}
- #call returns [type] //[Type type]
- #@init {List args = new ArrayList();}
- #: ^(CALL ID ^(ELIST (expr {args.add($expr.start);})*))
- # {
- # $type = symtab.call($ID, args);
- # $start.evalType = $type;
- # }
- #;
- def call( self,id,args):
- s = id.scope.resolve(id.getText())
- ms = s #(MethodSymbol)
- id.symbol = ms
- i = 0
- #for (Symbol a : ms.orderedArgs.values() ) { // for each arg
- for a in [item[1] for item in ms.orderedArgs]:
- #CymbolAST argAST = (CymbolAST)args.get(i++);
- argAST = args[i]
-
- # get argument expression type and expected type
- #Type actualArgType = argAST.evalType;
- actualArgType = argAST.evalType # liunote only CymbolAST has evalType ???
-
- #Type formalArgType = ((VariableSymbol)a).type; # liunote formaltype => int func (int j) ,but call is func (5+1.2)!!!
- formalArgType = a.type # formal is int index 3, actualArg is float index 4
- # promote[4][3]= None , int func(float) ,func(5) =>promote[3][4]= _float
- #int targ = actualArgType.getTypeIndex();
- #int tformal = formalArgType.getTypeIndex();
- targ = actualArgType.getTypeIndex()
- tformal = formalArgType.getTypeIndex()
-
- #// do we need to promote argument type to defined type?
- argAST.promoteToType = SymbolTable.promoteFromTo[targ][tformal]
-
- i += 1
-
- return ms.type
-
- #public Type member(CymbolAST expr, CymbolAST field) {
- # StructSymbol scope=(StructSymbol)expr.evalType;// get scope of left
- # Symbol s = scope.resolveMember(field.getText());// resolve ID in scope
- # field.symbol = s;
- # return s.type; // return ID's type
- #}
- #member returns [type] //[Type type]
- #: ^('.' expr ID)
- # {
- # $type = self.symtab.member($expr.start, $ID); // liunote struct a{ int b,...}[] => a[i].b ??? $expr.start what is ???
- # $start.evalType = $type; // liunote $expr => class expr_return (see below ), it derive TreeRuleReturnScope
- # } // $expr'start TreeRuleReturnScope 's start ()
- # // This is identical to the ParserRuleReturnScope except that
- # // the start property is a tree nodes not Token object
- # // when you are parsing trees. To be generic the tree node types
- # // have to be Object.
- #public static class expr_return extends TreeRuleReturnScope {
- # public Type type;
- #};
- #// $ANTLR start "expr"
- #// /Users/parrt/research/book/TPDSL/Book/code/semantics/promote/Types.g:39:1: expr returns [Type type] : ( 'true' | 'false' | CHAR | INT | FLOAT | ID | ^( UNARY_MINUS a= expr ) | ^( UNARY_NOT a= expr ) | member | arrayRef | call | binaryOps );
- #public final Types.expr_return expr() throws RecognitionException {
- # Types.expr_return retval = new Types.expr_return();
-
- def member(self, expr, field) :
- scope = expr.evalType # (StructSymbol) get scope of left
- s = scope.resolveMember(field.getText()) # resolve ID in scope
- field.symbol = s
- return s.type # return ID's type
-
- # assignnment stuff (arg assignment in call())
- #public void declinit(CymbolAST id, CymbolAST init) {
- # int te = init.evalType.getTypeIndex(); //promote expr to decl type?
- # int tdecl = id.symbol.type.getTypeIndex();
- # init.promoteToType = promoteFromTo[te][tdecl];
- #}
- #// START: datatransfer
- #decl: ^(VAR_DECL . ID (init=.)?) // call declinit if we have init expr
- # /*{if ( $init!=null && $init.evalType!=null )
- # symtab.declinit($ID, $init);}
- # *//* liunote $init=>CymbolAST */
- # {if $init!=None and $init.evalType!=None:
- # self.symtab.declinit($ID, $init);}
- #;
- def declinit(self, id, init) :
- te = init.evalType.getTypeIndex() # promote expr to decl type?
- tdecl = id.symbol.type.getTypeIndex()
- init.promoteToType = SymbolTable.promoteFromTo[te][tdecl]
- #ret : ^('return' v=.) {self.symtab.ret($start.symbol, $v);} //{symtab.ret((MethodSymbol)$start.symbol, $v);}
- #;
- def ret( self,ms, expr) :
- retType = ms.type; # promote return expr to function decl type? int m1(...) {return a;} a:expr, ms:int 's switch
- exprType = expr.evalType
- texpr = exprType.getTypeIndex()
- tret = retType.getTypeIndex()
- expr.promoteToType = SymbolTable.promoteFromTo[texpr][tret] # liunote at return get promote type
- #assignment // don't walk exprs, just examine types; '.' is wildcard
- #: ^('=
Symbol.py
- class Symbol(object): # A generic programming language symbol
- #public Symbol(String name) { this.name = name; }
- #public Symbol(String name, Type type) { this(name); this.type = type; }
- def __init__(self,name,type=None):
- self.name = '' # liunote use None ???
- self.scope = None
- self.type = None
- self.cymbolast_def = None # Location in AST of ID node liunote where use???
-
- self.name = name
-
- if type != None:
- self.type = type
- #public String getName() { return name; } # liunote getName must define ,for derive Type interface
- def getName(self):
- return self.name
- #name = property(getName) # liunote for sub get parent's member var !
- #def getType(self):
- # return self.type
- #type = property(getType) # liunote for sub class instance get parent's member var !
- #public String toString() {
- def toString(self):
- s = "";
- if self.scope != None : s = self.scope.getScopeName()+".";
- if self.type != None : return '<' + s + self.getName() + ":" + type + '>'
- return s + self.getName();
- #public static String stripBrackets(String s) {
- def stripBrackets(s):
- return s[1:len(s)-1] #s.substring(1,s.length()-1)
-
- stripBrackets = staticmethod(stripBrackets)
StructSymbol.py
- from Type import Type
- from Scope import Scope
- from ScopedSymbol import ScopedSymbol
- from SymbolTable import SymbolTable
- class StructSymbol (ScopedSymbol, Type, Scope):
-
- #Map<String, Symbol> fields = new LinkedHashMap<String, Symbol>();
- #public StructSymbol(String name,Scope parent) {super(name, parent);}
- def __init__(self,name,parent) :
- self.fields = []
- super(MethodSymbol,self).__init__(name, sparent)
-
- #/** For a.b, only look in a only to resolve b, not up scope tree */
- #public Symbol resolveMember(String name) { return fields.get(name); }
- def resolveMember(self,name):
- #return fields.get(name)
- for item in self.fields:
- if type(item) != tuple:
- raise RuntimeError('fields item is not tuple error')
- else:
- if item[0] == name:
- return item[1]
-
-
- #public Map<String, Symbol> getMembers() { return fields; }
- def getMembers(self):
- return fields
-
- def get(self,name):
- for item in self.fields:
- if type(item) != tuple:
- raise RuntimeError('fields item is not tuple')
- else:
- if item[0] == name:
- return item[1]
- #public String toString() {
- def toString(self):
- #return "struct "+name+":{"+ stripBrackets(fields.keySet().toString())+"}";
- return "struct " + self.name + "(" + ScopedSymbol.stripBrackets(str([item[0] for item in self.fields])) + ")"
-
- #public int getTypeIndex() { return SymbolTable.tUSER; }
- def getTypeIndex(self): # liunote other is buildin type ,this is user type
- return SymbolTable.tUSER
ScopedSymbol.py
- from Symbol import Symbol
- from Scope import Scope
- #public abstract class ScopedSymbol extends Symbol implements Scope {
- class ScopedSymbol (Symbol, Scope):
- #Scope enclosingScope;
- #public ScopedSymbol(String name, Type type, Scope enclosingScope) {
- # super(name, type);
- # this.enclosingScope = enclosingScope;
- #}
- #public ScopedSymbol(String name, Scope enclosingScope) {
- # super(name);
- # this.enclosingScope = enclosingScope;
- #}
-
- def __init__( self,name, enclosingScope,type):
-
- if type != None:
- super(ScopedSymbol,self).__init__(name, type)
- else:
- super(ScopedSymbol,self).__init__(name)
-
- #if isinstance(enclosingScope,Scope):
- # self.enclosingScope = enclosingScope # liunote use issubclass ???
- #else:
- # raise RuntimeError('enclosingScope is not instance of xScope')
-
- # liunote nouse above , when buidin type(derive smbol type) not derive from Scope !!!
- #print 'liutest enclosingScope'
- #print enclosingScope
- self.enclosingScope = enclosingScope
-
- #public Symbol resolve(String name) {
- def resolve(self,name):
- #s = self.getMembers().get(name) # this getMembers is abstract, subclass must implement this method !
- s = self.get(name)
- if s != None: return s
-
- #if not here, check any enclosing scope
- if self.getEnclosingScope() != None :
- return self.getEnclosingScope().resolve(name)
-
- return None # not found
-
- #public Symbol resolveType(String name) { return resolve(name); }
- def resolveType(self,name):
- return self.resolve(name)
-
- def define(self,sym):
- #self.getMembers().put(sym.name, sym)
- self.getMembers().append((sym.name, sym))
- sym.scope = self # track the scope in each symbol
- # liutest
- print self.getMembers()
- def getEnclosingScope(self):
- return self.enclosingScope
-
- def getScopeName(self):
- return self.name # liunote self.name at Symbol class => property(getName)
- #/** Indicate how subclasses store scope members. Allows us to
- # * factor out common code in this class.
- # */
- #public abstract Map<String, Symbol> getMembers();
- def getMembers(self): # ??? liunote if use below get,getMember can discard !
- abstract()
- # liunote for list get name
- def get(self,name):
- abstract()
Scope.py
- def abstract():
- raise NotImplementedError("abstract")
- class Scope(object):
-
- #def __init__(self):
- # if self.__class__ is Scope:
- # abstract()
- def getScopeName(self):
- abstract()
-
- # Where to look next for symbols
- def getEnclosingScope(self):
- abstract()
- # Define a symbol in the current scope
- def define(self,sym):
- abstract()
-
- # Look up name in this scope or in enclosing scope if not here
- def resolve(self,name):
- abstract()
阅读(1282) | 评论(0) | 转发(0) |