/*************************************************************** System JH-0.1 **\ ** SOURCE: ** ** ** ** Java Language Specification 2.0 ** ** - we use the same syntactic categories and rules of JLS 2.0 but for those ** ** that are using underscore in the name ** ** - we use standard syntax but we add the use of tag "var" to qualify local ** ** variable and to avoid unresolved collisions with the syntax of types ** ** (solution: complete rewriting of grammar rules given in the book. ** ** ** ** author: M. Bellia & M.E. Occhiuto - ** ** Univ. Pisa ** ** ** ********************************************************************************** ** JH-0.1 contains also a special treatment for mc-parameters. These parameters ** ** can be interpreted as m-parameter already applied to the class at the top of ** ** the class hierarchy which the actual methods are supposed to belong to. Thus ** ** this kind of parameter allows a check on the exitence of methods that can be ** ** effectively bound to formal mc-parameters of a method during its invocation ** \********************************************************************************/ %{ #include #include #include #include #include "SymTab.h" struct tab *SymTab; struct entry *Tobject; struct tab *Object; struct entry *Tbool; struct entry *Tbyte; struct entry *Tchar; struct entry *Tshort; struct entry *Tint; struct entry *Tfloat; struct entry *Tlong; struct entry *Tdouble; struct entry *Tvoid; FILE *err_file; // signals errors in the use of the extensions FILE *inspect_file; // for devolopment uses FILE *obj_file; // target file int lineno = 1; struct methList *mcollection = NULL; struct entryList *nullEList = NULL; %} %union { double dval; char *index; int bval; char cval; int ival; char *sval; struct stmList *code; struct tab *class; struct entry *pointerE; struct pair *pointerP; struct pair2 *pointerP2; struct pair3 *pointerP3; struct entryList *pointerV; struct funType *pointerF; struct sel *pointerS; struct sup_pam *pointerR; char *expr; } %start CompilationUnit %token FloatingPointLiteral %token Identifier %token BooleanLiteral %token IntegerLiteral %token StringLiteral %token CharacterLiteral %token Annotations VAR ArrayCreatorRest %token Tilde EXCLAMATION_MARK Plus2 Minus2 %token NULLLITERAL %token Eq PlusEq MinusEq ProdEq DivEq AmpEq BarEq UpEq PercEq MEq GEq MMeq %token SOr SAnd Or XOr And BEq NEq LT GT LE GE %token BLT BGT MBG Plus Minus Times IDiv FDiv %token DOT DOT_STAR QUESTION_MARK COMMA COL SEMIC O_A O_B O_C C_A C_B C_C %token SUPER NEW VOID THIS %token INSTANCEOF CLASS IF FOR WHILE DO TRY SWITCH BREAK RETURN THROW %token CONTINUE FINALLY CASE CATCH DEFAULT PACKAGE IMPORT EXTENDS %token IMPLEMENTS INTERFACE THROWS STATIC ELSE %token PUBLIC PRIVATE PROTECTED FINAL NATIVE SYNCHRONIZED ABSTRACT %token BOOLEAN BYTE CHAR SHORT INT FLOAT LONG DOUBLE %token FUN Into ABS FUNCTIONAL %nonassoc IFX %nonassoc ELSE %nonassoc BRK %nonassoc VIR %nonassoc lowerThanC_A %nonassoc lowerThanSemi %nonassoc C_A %nonassoc Identifier %nonassoc Plus %nonassoc Minus %nonassoc VOID %nonassoc BOOLEAN %nonassoc BYTE %nonassoc CHAR %nonassoc SHORT %nonassoc INT %nonassoc FLOAT %nonassoc LONG %nonassoc DOUBLE %nonassoc lowerThanDot %nonassoc DOT %nonassoc O_B %nonassoc lowerThanPlus %left Plus2 %left Minus2 %type Literal %type TypeList %type MarkC3 MarkI3 %type NewMeth NewMeth2 %type MethodDeclaratorRest Constructor_Or_Void_Meth_DeclaratorRest %type SymType SymVar SymVar1 NewId NewVar NewPar NewTypeClass %type VariableDeclarator VariableDeclaratorId Ext_Type FormalParameter %type Type BasicType Ext_TypeList NewTypeInterface %type MethodOrFieldRest %type VariableDeclarators VariableDeclarators_List FormalParameters %type FormalParameters_List Type_List %type Block MethodBody MethodBody_OrEmpty %type Expression ParExpression VariableInitializer ArrayInitializer %type VariableInitializer_Seq VariableInitializer_List Creator %type Comma_Opt InnerCreator ClassCreatorRest Array_Class_Rest %type QualifiedIdentifier Ext_Expression BracketsOpt Expr_Or_Type %type Expression3 Expression3_Opt InfixOp Expression1Rest Expression1 %type StatementExpression Expression2 Expression2Rest_Opt PrefixOp %type Assign_Opt AssignmentOperator Expression_Opt Identifier_Opt %type PostfixOp PostfixOp_Seq Identifier_Seq ConstantExpression %type Selector SuperSuffix Selector_List Primary %type Arguments Expression_Seq Expression_List Arguments_Opt %type IdentifierSuffix %% QualifiedIdentifier: Identifier Identifier_Seq SymVar1 {// code translation rules: begin $$ = concat($1,$2); } SymVar1:{ atomicFlag = 1; $$ = symlook(concat($-1,$0)); } Identifier_Seq: DOT Identifier Identifier_Seq SymVar { $$ = concat(".",concat($2,$3)); } | {$$ = "";} ; Literal: IntegerLiteral {$$ = $1;} | FloatingPointLiteral {$$ = $1;} | CharacterLiteral {$$ = $1;} | StringLiteral {$$ = $1;} | BooleanLiteral {$$ = $1;} | NULLLITERAL {$$ = "null";} ; Expression: Expression1 Assign_Opt {// code translation rules: begin $$ = concat($1,$2); } Assign_Opt: AssignmentOperator Expression1 {// code translation rules: begin $$ = concat($1,$2); } | {// code translation rules: begin $$ = ""; } ; AssignmentOperator: Eq {// code translation rules: begin $$ = strdup(" = "); } | PlusEq {// code translation rules: begin $$ = strdup(" += "); } | MinusEq {// code translation rules: begin $$ = strdup(" -= "); } | ProdEq {// code translation rules: begin $$ = strdup(" *= "); } | DivEq {// code translation rules: begin $$ = strdup(" /= "); } | AmpEq {// code translation rules: begin $$ = strdup(" &= "); } | BarEq {// code translation rules: begin $$ = strdup(" |= "); } | UpEq {// code translation rules: begin $$ = strdup(" ^= "); } | PercEq {// code translation rules: begin $$ = strdup(" %= "); } | MEq {// code translation rules: begin $$ = strdup(" <<= "); } | GEq {// code translation rules: begin $$ = strdup(" >>= "); } | MMeq {// code translation rules: begin $$ = strdup(" >>>= "); } ; Type: FUN Type_List Into Type { // code translation rules: begin $$ = insertF(SymTab,new_funType($2,$4)); // ignora packages e tipi path } | FUN Type_List Into VOID { // code translation rules: begin $$ = insertF(SymTab,new_funType($2,Tvoid)); // ignora packages e tipi path } | Identifier Identifier_Seq BracketsOpt SymType { $$ = $4; } | BasicType { $$ = $1; } ; Type_List: Type Type_List { $$ = cons($1,$2); } | { $$ = NULL; } ; SymType: {atomicFlag = 1; $$ = symlook(concat($-2,concat($-1,$0)));} BasicType: BOOLEAN { $$ = Tbool; } | BYTE { $$ = Tbyte; } | CHAR { $$ = Tchar; } | SHORT { $$ = Tshort; } | INT { $$ = Tint; } | FLOAT { $$ = Tfloat; } | LONG { $$ = Tlong; } | DOUBLE { $$ = Tdouble; } ; StatementExpression: Expression { // code translation rules: begin $$ = $1; } ; ConstantExpression: Expression { // code translation rules: begin $$ = $1; } ; Expression1: Expression2 Expression1Rest { $$ = concat($1,$2); } ; Expression1Rest: QUESTION_MARK Expression COL Expression1 { $$ = concat("?",concat($2,concat(":",$4))); } | %prec lowerThanC_A // to avoid 1 shift/reduce conflict {// code translation rules: begin $$ = ""; } ; Expression2: Expression3 Expression2Rest_Opt { $$ = concat($1,$2); } Expression2Rest_Opt: InfixOp Expression2 { $$ = concat($1,$2); } | INSTANCEOF Type {// code translation rules: begin if (($2->type == 0)||($2->type == -1)) $$=concat("instanceof ",$2->lexeme); else $$=concat("instanceof ","String"); } | {// code translation rules: begin $$ = ""; } ; InfixOp: SOr {// code translation rules: begin $$ = strdup(" | "); } | SAnd {// code translation rules: begin $$ = strdup(" & "); } | Or {// code translation rules: begin $$ = strdup(" || "); } | XOr {// code translation rules: begin $$ = strdup(" ^ "); } | And {// code translation rules: begin $$ = strdup(" && "); } | BEq {// code translation rules: begin $$ = strdup(" == "); } | NEq {// code translation rules: begin $$ = strdup(" != "); } | LT {// code translation rules: begin $$ = strdup(" < "); } | GT {// code translation rules: begin $$ = strdup(" > "); } | LE {// code translation rules: begin $$ = strdup(" <= "); } | GE {// code translation rules: begin $$ = strdup(" >= "); } | BLT {// code translation rules: begin $$ = strdup(" << "); } | BGT {// code translation rules: begin $$ = strdup(" >> "); } | MBG {// code translation rules: begin $$ = strdup(" >>> "); } | Plus {// code translation rules: begin $$ = strdup(" + "); } | Minus {// code translation rules: begin $$ = strdup(" - "); } | Times {// code translation rules: begin $$ = strdup(" * "); } | IDiv {// code translation rules: begin $$ = strdup(" / "); } | FDiv {// code translation rules: begin $$ = strdup(" % "); } ; Expression3: PrefixOp Expression3 {// code translation rules: begin $$ = concat($1,$2); } | Primary Selector_List PostfixOp_Seq {// code translation rules: begin char *exp = emitApplyCall($1,$2); $$ = concat(exp,$3); fprintf(inspect_file,"ciclo exit %s %d %d\n",exp,strlen(exp),strlen("literal")); } ; Expression3_Opt: Expression3 {// code translation rules: begin $$ = concat("(",concat($1,")")); } | %prec lowerThanSemi {// code translation rules: begin $$ = ""; } ; PrefixOp: Plus2 {// code translation rules: begin $$ = strdup(" ++"); } | Minus2 {// code translation rules: begin $$ = strdup(" --"); } | Plus {// code translation rules: begin $$ = strdup(" +"); } | Minus {// code translation rules: begin $$ = strdup(" -"); } | Tilde {// code translation rules: begin $$ = strdup(" ~"); } | EXCLAMATION_MARK {// code translation rules: begin $$ = strdup(" !"); } ; PostfixOp_Seq: PostfixOp PostfixOp_Seq { // code translation rules: begin $$ = concat($1,$2); } | %prec lowerThanPlus { // code translation rules: begin $$ = ""; } ; PostfixOp: Plus2 {// code translation rules: begin $$ = strdup("++"); } | Minus2 {// code translation rules: begin $$ = strdup("--"); } ; Expr_Or_Type: O_A Expression C_A {// code translation rules: begin $$ = concat("(",concat($2,")")); } ; BracketsOpt: O_B C_B BracketsOpt {// code translation rules: begin $$ = concat("[]",$3); } | {// code translation rules: begin $$ = ""; } ; Primary: Expr_Or_Type Expression3_Opt {// code translation rules: begin $$ = new_sel(1,concat($1,$2),NULL,NULL); } | THIS Arguments_Opt {// code translation rules: begin $$ = new_sel(1,"this",$2,NULL); } | SUPER SuperSuffix {// code translation rules: begin struct sel *temp = $2; if(temp->flag == 5) { temp->main = "super"; $$ = temp; } else $$ = new_sel(1,"super",NULL,$2); } | Literal {// code translation rules: begin $$ = new_sel(1,$1,NULL,NULL); } | NEW Creator {// code translation rules: begin $$ = new_sel(1,concat("new ",$2),NULL,NULL); } | Identifier IdentifierSuffix SymVar {// code translation rules: begin $$ = new_sel(7,$1,$2,NULL); } | BasicType BracketsOpt DOT CLASS {// code translation rules: begin $$ = new_sel(1,concat($1->lexeme,concat($2,".class")),NULL,NULL); } | VOID DOT CLASS {// code translation rules: begin $$ = new_sel(1,"void.class",NULL,NULL); } ; SymVar: { atomicFlag = 2; $$ = symlook($-1); } Selector_List: Selector Selector_List {// code translation rules: begin if ($2!=NULL) { struct sel *cur; for(cur=$1;cur->seq!=NULL;cur=cur->seq); cur->seq=$2; } $$ = $1; } | %prec lowerThanDot {// code translation rules: begin $$ = NULL; } ; Selector: DOT Identifier IdentifierSuffix {// code translation rules: begin $$ = new_sel(0,$2,$3,NULL); } | DOT THIS {// code translation rules: begin $$ = new_sel(1,".this",NULL,NULL); } | DOT SUPER SuperSuffix {// code translation rules: begin struct sel *temp = $3; if(temp->flag == 5) { temp->main = ".super"; $$ = temp; } else $$ = new_sel(1,".super",NULL,$3); } | DOT NEW InnerCreator {// code translation rules: begin $$ = new_sel(1,concat(".new",$3),NULL,NULL); } | O_B Expression C_B {// code translation rules: begin $$ = new_sel(1,concat("[",concat($2,"]")),NULL,NULL); } ; IdentifierSuffix: Arguments {// code translation rules: begin $$ = $1; } | {// code translation rules: begin $$ = NULL; } ; SuperSuffix: Arguments { // code translation rules: begin $$ = new_sel(5,"",$1,NULL); } | DOT Identifier Arguments_Opt SymVar {// code translation rules: begin $$ = new_sel(6,$2,$3,NULL); } ; Arguments_Opt: Arguments {// code translation rules: begin $$ = $1; } | {// code translation rules: begin $$ = NULL; // controllare e modificare } ; Arguments: O_A Expression_List C_A { // code translation rules: begin $$ = $2; } Expression_List: Ext_Expression Expression_Seq { // code translation rules: begin $$ = consR($1,$2); } | { // code translation rules: begin $$ = consR("",NULL); } ; Expression_Seq: COMMA Ext_Expression Expression_Seq {// code translation rules: begin $$ = consR($2,$3); } | {// code translation rules: begin $$ = NULL; } ; Ext_Expression: ABS QualifiedIdentifier { // code translation rules: begin $$=concat("\"",concat(strdup($2),"\"")); } | Expression { // code translation rules: begin $$=$1; } ; Creator: QualifiedIdentifier Array_Class_Rest {// code translation rules: begin $$=concat($1,concat(" ",$2)); } Array_Class_Rest: ArrayCreatorRest {// code translation rules: begin char *temp=malloc(strlen("ArrayCreatorRest")*sizeof(char)); strcpy(temp,"ArrayCreatorRest"); $$ = temp; fprintf(inspect_file, "warning: ArrayCreatorRest \n"); //to consider } | ClassCreatorRest {// code translation rules: begin $$ = $1; } ; InnerCreator: Identifier ClassCreatorRest SymVar {// code translation rules: begin $$ = concat($1,$2); } ClassCreatorRest: Arguments {// code translation rules: begin (computes $$=flatten($1)) char *temp = "("; struct sup_pam *cur; for(cur=$1; cur!=NULL; cur=cur->tl) { temp = concat(temp,cur->hd); if (cur->tl!=0)temp=concat(temp,","); }; $$ = concat(temp,")"); } ArrayInitializer: O_C Comma_Opt C_C {// code translation rules: begin $$ = concat("{",concat($2,"}")); } Comma_Opt: VariableInitializer_List { // code translation rules: begin $$ = $1; } | COMMA { // code translation rules: begin $$ = ","; } ; VariableInitializer_List: VariableInitializer VariableInitializer_Seq {// code translation rules: begin $$ = concat($1,$2); } | {// code translation rules: begin $$ = ""; } ; VariableInitializer_Seq: COMMA VariableInitializer VariableInitializer_Seq // stop here {// code translation rules: begin $$ = concat(",",concat($2,$3)); } | {// code translation rules: begin $$ = ""; } ; VariableInitializer: ArrayInitializer {// code translation rules: begin $$ = $1; } | Expression {// code translation rules: begin $$ = $1; } ; ParExpression: O_A Expression C_A {// code translation rules: begin $$ = concat("(",concat($2,")")); } Block: O_C Mark1 BlockStatements Mark2 C_C { $$ = NULL; } Mark1: { SymTab = (struct tab *) new_tab(1,SymTab); // code translation rules: begin fprintf(obj_file,"{\n"); } ; Mark2: { SymTab = SymTab->up; // code translation rules: begin fprintf(obj_file,"}\n"); } ; BlockStatements: B_tab BlockStatement BlockStatements | ; B_tab: { // code translation rules: begin fprintf(obj_file,"\t"); } ; BlockStatement: LocalVariableDeclarationStatement SEMIC { // code translation rules: begin fprintf(obj_file,";\n"); } | ClassOrInterfaceDeclaration | Statement ; LocalVariableDeclarationStatement: VAR FINAL Final_out Type Type_Out VariableDeclarators { addType($6,$4); } | VAR Type Type_Out VariableDeclarators { addType($4,$2); } | error VariableDeclarators {warning("var omitted in local variable declaration",(char *)0);} ; Final_out: { // code translation rules: begin fprintf(obj_file,"final"); } ; Type_Out: { // code translation rules: begin struct entry *ty = $0; if(ty->type == -3) fprintf(obj_file,"String"); else fprintf(obj_file,"%s ",ty->lexeme); } ; Statement: Block | IF ParExpression If_Out Statement %prec IFX | IF ParExpression If_Out Statement ELSE Else_Out Statement | FOR O_A For_Out ForInitOpt SEMIC Expression_Opt SEMIC Semic_Out1 ForUpdateOpt C_A CA_Out Statement | WHILE ParExpression While_Out Statement | DO Do_Out Statement WHILE ParExpression SEMIC Semic_Out2 | TRY Try_Out Block Catc_Or_Bloc | SWITCH ParExpression O_C Switch_Out SwitchBlockStatementGroups C_C CC_Out | SYNCHRONIZED ParExpression Syn_Out Block | RETURN Expression_Opt SEMIC Semic_Out3 | THROW Expression SEMIC Semic_Out4 | BREAK Identifier_Opt SEMIC Semic_Out5 | CONTINUE Identifier_Opt SEMIC Semic_Out6 | SEMIC Semic_Out | ExpressionStatement | Identifier NewId COL Col_Out Statement | error SEMIC ; If_Out: { //code translation rules: begin char *pe = $0; fprintf(obj_file,"if %s",pe); } ; Else_Out: { //code translation rules: begin fprintf(obj_file, "else "); } For_Out: { //code translation rules: begin fprintf(obj_file, "for("); } Semic_Out1: { //code translation rules: begin fprintf(obj_file, ";%s;", $-1); } CA_Out: { //code translation rules: begin fprintf(obj_file, ")"); } While_Out: { //code translation rules: begin char *pe = $0; fprintf(obj_file, "while %s", pe); } Semic_Out2: { //code translation rules: begin char *pe = $-1; fprintf(obj_file, "while %s;\n", pe); } Do_Out: { //code translation rules: begin fprintf(obj_file, "do"); } Try_Out: { //code translation rules: begin fprintf(obj_file, "try"); } Switch_Out: { //code translation rules: begin char *pe = $-1; fprintf(obj_file,"switch %s{\n",pe); } CC_Out: { //code translation rules: begin fprintf(obj_file, "}"); } Syn_Out: { //code translation rules: begin char *pe = $0; fprintf(obj_file, "syncronized %s", pe); } Semic_Out3: { //code translation rules: begin fprintf(obj_file, "return %s;", $-1); } Semic_Out4: { //code translation rules: begin fprintf(obj_file, "throw %s;", $-1); } Semic_Out5: { //code translation rules: begin fprintf(obj_file, "break %s;", $-1); } Semic_Out6: { //code translation rules: begin fprintf(obj_file, "continue %s;", $-1); } Semic_Out: { //code translation rules: begin fprintf(obj_file,";\n"); } Col_Out: { //code translation rules: begin fprintf(obj_file, "%s:", $-2); } NewId: { atomicFlag = 1; $$ = symlook($0); } Expression_Opt: Expression {$$ = $1;} | {$$ = "";} ; Identifier_Opt: Identifier {$$ = $1;} | {$$ = "";} ; Catc_Or_Bloc: Catches | Catches FINALLY Finally_Out Block | FINALLY Finally_Out Block ; Finally_Out: { // code translation rules: begin fprintf(obj_file, "finally"); } SwitchBlockStatementGroups: SwitchBlockStatementGroup SwitchBlockStatementGroups | ; Catches: CatchClause CatchClause_List CatchClause_List: CatchClause CatchClause_List | ; CatchClause: CATCH O_A Catch_Outp FormalParameter C_A Catch_Outf Block Catch_Outp: { //code translation rules: begin fprintf(obj_file,"catch ("); } Catch_Outf: { //code translation rules: begin fprintf(obj_file,")"); } SwitchBlockStatementGroup: SwitchLabel BlockStatements SwitchLabel: CASE ConstantExpression COL Col_Out2 | DEFAULT { // code translation rules: begin fprintf(obj_file, "default"); } ; Col_Out2: { // code translation rules: begin fprintf(obj_file, "case %s:", $-1); } MoreStatementExpressions: COMMA StatementExpression Comma_out1 MoreStatementExpressions | Comma_out1: { // code translation rules: begin fprintf(obj_file, ",%s", $0); } ForInitOpt: ForInit | ; ForInit: FINAL Type Type_Out1 VariableDeclarators { addType($4,$2); } | Type Type_Out2 VariableDeclarators { addType($3,$1); } | VariableDeclarators ; Type_Out1: { // code translation rules: begin struct entry *ty = $0; if(ty->type == -3) fprintf(obj_file, "final String"); else fprintf(obj_file, "final %s", ty->lexeme); } Type_Out2: { // code translation rules: begin struct entry *ty = $0; if(ty->type == -3) fprintf(obj_file, "String"); else fprintf(obj_file, "%s", ty->lexeme); } ForUpdateOpt: ForUpdate | ; ForUpdate: StatementExpression F_Out MoreStatementExpressions F_Out: { // code translation rules: begin fprintf(obj_file, "%s", $0); } ModifiersOpt: Modifier ModifiersOpt | ; Modifier: PUBLIC { // code translation rules: begin fprintf(obj_file,"public "); } | PRIVATE { // code translation rules: begin fprintf(obj_file,"private "); } | PROTECTED { // code translation rules: begin fprintf(obj_file,"protected "); } | STATIC { // code translation rules: begin fprintf(obj_file,"static "); } | FINAL { // code translation rules: begin fprintf(obj_file,"final "); } | NATIVE { // code translation rules: begin fprintf(obj_file,"native "); } | SYNCHRONIZED { // code translation rules: begin fprintf(obj_file,"syncronized "); } | ABSTRACT { // code translation rules: begin fprintf(obj_file,"abstract "); } | FUNCTIONAL { // code translation rules: begin setOn(); // -- traversal of a class that must implement // -- interface ApplyClass: which is following // -- modifier_opt checks the tag and, suitably, // -- sets a stack for traversals of deeper classes } ; ExpressionStatement: StatementExpression SEMIC { // code translation rules: begin fprintf(obj_file, "%s;\n", $1); } VariableDeclarators: VariableDeclarator VariableDeclarators_List { $$ = cons($1,$2); } VariableDeclarators_List: COMMA Comma_Out VariableDeclarator VariableDeclarators_List { $$ = cons($3,$4); } | { $$ = nullEList; } ; VariableDeclarator: Identifier NewVar VariableDeclaratorRest { $$ = $2; } NewVar: { atomicFlag = 1; $$ = symlook($0); // code translation rules: begin fprintf(obj_file, "%s", $$->lexeme); } VariableDeclaratorRest: Init_Opt Init_Opt: Eq VariableInitializer Eq_Out | ; Eq_Out: { // code translation rules: begin fprintf(obj_file, "= %s", $0); } ConstantDeclaratorRest: BracketsOpt Eq VariableInitializer Eq_Out2 Eq_Out2: { // code translation rules: begin fprintf(obj_file, "%s = %s", $-2, $0); } VariableDeclaratorId: Identifier BracketsOpt NewPar { $$ = $3; } NewPar: { atomicFlag = 1; $$ = symlook($-1); // code translation rules: begin fprintf(obj_file, "%s%s", $-1, $0); } CompilationUnit: PACKAGE QualifiedIdentifier SEMIC_Out8 ImportDeclaration_List TypeDeclaration_List | ImportDeclaration_List TypeDeclaration_List ; SEMIC_Out8: SEMIC { // code translation rules: begin char *temp = concat("package",$0); fprintf(obj_file,temp); } ImportDeclaration_List: ImportDeclaration ImportDeclaration_List { fprintf(inspect_file,"\ntype checking unfair: The program is using import\n\n"); } | ; ImportDeclaration: IMPORT Identifier Import_Out Identifier_Path { // code translation rules: begin fprintf(obj_file,";\n"); } Import_Out: { // code translation rules: begin fprintf(obj_file, "import %s", $0); } Identifier_Path: DOT Identifier Dot_Out Identifier_Path | DOT_STAR SEMIC { // code translation rules: begin fprintf(obj_file, ".*"); } | SEMIC { // code translation rules: begin fprintf(obj_file, ""); } ; Dot_Out: { // code translation rules: begin fprintf(obj_file, ".%s", $0); } TypeDeclaration_List: TypeDeclaration TypeDeclaration_List | ; TypeDeclaration: ClassOrInterfaceDeclaration ClassOrInterfaceDeclaration: ModifiersOpt XXX ClassDeclaration | ModifiersOpt XXX InterfaceDeclaration ; XXX: { if (isSetOn()) pushOn(); else pushOff(); } ClassDeclaration: CLASS YYY Identifier NewTypeClass Ext_Type MarkC3 Imp_TypeList ClassBody {// code translation rules: begin if (topOn()) { struct methListOfList *temp = toMethListOfList(SymTab); fprintf(obj_file,"%s", emitApplyDisp(temp)); fprintf(obj_file,"%s", emitApplyList(temp)); } fprintf(obj_file,"}\n"); popOnOff(); //advanced analysis SymTab = $6; } YYY: {resetOff();} // for nested class traversal NewTypeClass: { atomicFlag = 0; struct entry *temp = symlook($0); $$ = temp; fprintf(inspect_file,"LINENO %d\n", lineno); // code translation rules: begin fprintf(obj_file, "class %s ", $0); } NewTypeInterface: { atomicFlag = 4; struct entry *temp = symlook($0); $$ = temp; fprintf(inspect_file,"LINENO %d\n", lineno); // code translation rules: begin fprintf(obj_file, "interface %s ", $0); } MarkC3: { struct tab *tempTab = SymTab; struct entry *temp = $0; struct entry *cl = $-1; SymTab = cl->val.class; if (temp->type == 0) SymTab->up = temp->val.class; else SymTab->up = Object; // in questo caso extends non ha una classe nota. struct entry *temptype = insertT(SymTab, $-2, SymTab); temptype->type = -2; current_class = $-2; $$ = tempTab; // code translation rules: begin } Ext_Type: EXTENDS Type { $$ = $2; // code translation rules: begin struct entry *ty = $2; if(ty->type == -3) fprintf(obj_file, "extends String "); //errore else fprintf(obj_file, "extends %s ", ty->lexeme); } | { $$ = Tobject;} ; Imp_TypeList: IMPLEMENTS Apply_Imp Type Implements_Out TypeList | { // code translation rules: begin if (topOn()) fprintf(obj_file, "implements ApplyClass"); } ; Apply_Imp: { fprintf(obj_file, "implements "); if (topOn()) fprintf(obj_file, "ApplyClass"); } Implements_Out: { // code translation rules: begin struct entry *ty = $0; if(ty->type == -3) fprintf(obj_file,"String "); //errore else fprintf(obj_file,", %s ",ty->lexeme); } InterfaceDeclaration: INTERFACE Identifier NewTypeInterface Ext_TypeList MarkI3 InterfaceBody { // code translation rules: begin if (topOn()) { char *p = "flag for m_parameter is set on in the interface: LINENO %d\n"; fprintf(inspect_file, p,lineno); fprintf(err_file, "an interface cannot extends interface applyClass: LINENO %d\n", lineno); } fprintf(obj_file,"}\n"); popOnOff(); resetOff(); // for a new class traversal //advanced analysis SymTab = $5; } Ext_TypeList: EXTENDS Type Extends_Out TypeList { $$ = $2; char *p = "type checking may be unfair when interface has more then one extentions"; if($4 == 0)fprintf(inspect_file, "\n%s", p); } | { $$ = Tobject; } ; Extends_Out: { // code translation rules: begin struct entry *ty = $0; if(ty->type == -3) fprintf(obj_file, "extends String "); //errore else fprintf(obj_file, "extends %s ", ty->lexeme); } TypeList: COMMA Type T_Out TypeList { $$ = 0; } | { $$ = 1; } ; T_Out: { // code translation rules: begin struct entry *ty = $0; if(ty->type == -3) fprintf(obj_file, ", String "); //errore else fprintf(obj_file, ",%s ", ty->lexeme); } MarkI3: { struct tab *tempTab = SymTab; struct entry *temp = $0; struct entry *cl = $-1; SymTab = cl->val.class; if (temp->type == 0) SymTab->up = temp->val.class; else SymTab->up = Object; // in questo caso extends non ha una classe nota. struct entry *temptype = insertT(SymTab, $-2, SymTab); temptype->type = -2; current_class = $-2; $$ = tempTab; // code translation rules: begin } ClassBody: O_C OC_Out ClassBodyDeclaration_list C_C { // code translation rules: begin } InterfaceBody: O_C OC_Out InterfaceBodyDeclaration_list C_C { // code translation rules: begin } OC_Out: { // code translation rules: begin fprintf(obj_file, "{\n"); } ClassBodyDeclaration_list: ClassBodyDeclaration ClassBodyDeclaration_list | ; ClassBodyDeclaration: SEMIC { // code translation rules: begin fprintf(obj_file, ";\n"); } | Static_Opt Block | MemberDecl ; Static_Opt: STATIC { // code translation rules: begin fprintf(obj_file, "static "); } | ; MemberDecl: ModifiersOpt NoVoid_MethodOrFieldDecl | ModifiersOpt VOID PVoid Identifier NewMeth Constructor_Or_Void_Meth_DeclaratorRest { struct entry *class = find0($5->t,current_class); // check: --- nullary???? struct meth *u = $5->e->val.addr->data.mt; meth_reset(u, class, $6->ty, NULL, $6->cc); mcollection = mcons(u,mcollection); SymTab = $5->t; } | ModifiersOpt Identifier NewMeth Constructor_Or_Void_Meth_DeclaratorRest { struct entry *class = find0($3->t,current_class); // check: --- nullary???? struct meth *u = $3->e->val.addr->data.mt; if (u->name == class->lexeme) meth_reset(u, class, $4->ty, class, $4->cc); else meth_reset(u, class, $4->ty, NULL, $4->cc); mcollection = mcons(u,mcollection); SymTab = $3->t; } | ClassOrInterfaceDeclaration ; PVoid: { // code translation rules: begin fprintf(obj_file, "void "); } NewMeth: { atomicFlag = 3; struct entry *temp = symlook($0); struct pair *temp2 = (struct pair*)malloc(sizeof(struct pair)); temp2->t = SymTab; temp2->e = temp; $$ = temp2; struct rec *var1 = temp->val.addr; struct meth *var2 = var1->data.mt; struct tab *var3 = var2->block; SymTab = var2->block; SymTab->up = temp2->t; // meth. body is in the scope of the class // code translation rules: begin fprintf(obj_file, "%s ", temp->lexeme); } NoVoid_MethodOrFieldDecl: Type Identifier NewMeth2 MethodOrFieldRest MarkVar { struct pair3 *p3 = $4; if ($4->bval == 0) { struct pair2 *p2 = $4->val; struct entry *class = find0($3->t,current_class); // check: -- nullary? struct meth *u = $3->e->val.addr->data.mt; meth_reset(u, class, p2->ty, $1, p2->cc); mcollection = mcons(u,mcollection); }; SymTab = $3->t; } NewMeth2: { atomicFlag = 3; struct entry *temp = symlook($0); struct pair *temp2 = (struct pair*)malloc(sizeof(struct pair)); temp2->t = SymTab; temp2->e = temp; $$ = temp2; SymTab = temp->val.addr->data.mt->block; SymTab->up = temp2->t; // meth. body is in the scope of the class // code translation rules: begin struct entry *ty = $-1; fprintf(obj_file, "%s %s ",ty->lexeme,temp->lexeme); } MethodOrFieldRest: VariableDeclaratorRest { // for variable $$ = new_pair3(1,NULL); } | MethodDeclaratorRest { // for method $$ = new_pair3(0,$1); } ; MarkVar: { struct pair3 *p3 = $0; if (p3->bval == 1) { struct pair *temp2 = $-1; struct entry *temp = temp2->e; temp->type = 1; temp->val.addr = new_rec_f(new_field(0)); }; } InterfaceBodyDeclaration_list: InterfaceBodyDeclaration InterfaceBodyDeclaration_list | ; InterfaceBodyDeclaration: SEMIC { // code translation rules: begin fprintf(obj_file, ";\n"); } | InterfaceMemberDecl ; InterfaceMemberDecl: ModifiersOpt InterfaceMethodOrFieldDecl | ModifiersOpt VOID Identifier ZZZ InterfaceMethodDeclaratorRest | ClassOrInterfaceDeclaration ; ZZZ: { // code translation rules: begin fprintf(obj_file, "void %s", $0); } InterfaceMethodOrFieldDecl: Type Identifier Int_out InterfaceMethodOrFieldRest Int_out: { // code translation rules: begin fprintf(obj_file, "%s %s ", $-1->lexeme, $0); } InterfaceMethodOrFieldRest: ConstantDeclaratorRest SEMIC | InterfaceMethodDeclaratorRest ; MethodDeclaratorRest: FormalParameters Throws_Opt MethodBody_OrEmpty { $$ = new_pair2($1,$3); } Throws_Opt: THROWS QualifiedIdentifier Throws_Out2 QualifiedIdentifierList | ; Throws_Out2: { // code translation rules: begin fprintf(obj_file, "throws %s", $0); } MethodBody_OrEmpty: MethodBody { $$ = $1; } | SEMIC { $$ = NULL; // code translation rules: begin fprintf(obj_file, ";\n"); } ; InterfaceMethodDeclaratorRest: FormalParameters Throws_Opt SEMIC { // code translation rules: begin fprintf(obj_file, ";\n"); } Constructor_Or_Void_Meth_DeclaratorRest: FormalParameters Throws_Opt MethodBody { $$ = new_pair2($1,$3); } QualifiedIdentifierList: COMMA QualifiedIdentifier Comma_Out2 QualifiedIdentifierList | ; FormalParameters: O_A OA_Out FormalParameter FormalParameters_List C_A { $$ = cons($3,$4); // code translation rules: begin fprintf(obj_file,strdup(")")); } | O_A C_A { $$ = NULL; // code translation rules: begin fprintf(obj_file,strdup("()")); } ; OA_Out: { // code translation rules: begin fprintf(obj_file, strdup("(")); } FormalParameters_List: COMMA Comma_Out FormalParameter FormalParameters_List { $$ = cons($3,$4); } | { $$ = NULL; } ; Comma_Out: { // code translation rules: begin fprintf(obj_file, strdup(",")); } Comma_Out2: { // code translation rules: begin fprintf(obj_file, ",%s", $0); } FormalParameter: FINAL Type Type_Out3 VariableDeclaratorId { $$ = $2; // code translation rules: begin $4->trueType = $2; } | Type Type_Out4 VariableDeclaratorId { $$ = $1; // code translation rules: begin $3->trueType = $1; } ; Type_Out3: { // code translation rules: begin struct entry* temp = $0; if (temp->type == -3) fprintf(obj_file, "final String "); else fprintf(obj_file, "final %s ", temp->lexeme); } Type_Out4: { // code translation rules: begin struct entry* temp = $0; if (temp->type == -3) fprintf(obj_file, "String "); else fprintf(obj_file, "%s ", temp->lexeme); } MethodBody: Block { $$ = $1; } %% //--------------------------------- main part: declaration #define DEFAULT_OutFile "ABSTRACT.txt" // tables, abstract syntax and // other items about the source char *program = "Java"; int varfun; struct stack *OnOff; struct entry *Tinteger; struct entry *undef; // unit of the objects char *usage = "%s: usage [INFILE] [OUTFILE] \n"; char *err1E3 = "e: (ty->type == -3) but (exp != "") in 3d clause of Expr3\n"; char *err2E3 = "e: the number of actual and formal parameter mismatches\n"; char *err3E3 = "e: non p_meth parameter used as a p_meth\n"; char *err4E3 = "e: test on (temp!=NULL)&&(temp->type>0) fails in 3d clause of Exp3\n"; // FILE *temporary; temporary to store (partially) translated code to update int yyerrflag = 1; //----- end declaration //------- from SymTab2 int topOn() { return (OnOff!=NULL)&&(OnOff->top == 0); } void popOnOff() { if (OnOff == NULL) fprintf(inspect_file,"anomalia nella gestione dello stack OnOff: pop su stack vuoto\n"); else OnOff = OnOff -> pop; } void newOnOff(int n) { struct stack *temp = (struct stack *)malloc(sizeof(struct stack)); temp -> top = n; temp -> pop = OnOff; OnOff = temp; } void pushOn() { newOnOff(0); } void pushOff() { newOnOff(1); } int isSetOn() { return varfun == 0; } void resetOff() { varfun = 1; } void setOn() { varfun = 0; } int hash(char *s) { int h = 0; int i; for(i=0; ilexeme = s; temp->type = 1; temp->val.addr = a; temp->next_e = e; return temp; } struct entry *new_entryF(char *s, struct funType* f, struct entry *e) { struct entry *temp; temp = (struct entry*) malloc(sizeof(struct entry)); temp->lexeme = s; temp->type = -3; temp->val.type = f; temp->next_e = e; return temp; } struct rec *new_rec_f(struct field* vfd) { struct rec *temp; temp = (struct rec*) malloc(sizeof(struct rec)); temp->type = 1; temp->data.fd = vfd; return temp; } struct rec *new_rec_m(struct meth* vmt) { struct rec *temp; temp = (struct rec*) malloc(sizeof(struct rec)); temp->type = 3; temp->data.mt = vmt; return temp; } struct entry *new_entryT(char *s, struct tab* t, struct entry *e) { struct entry *temp; temp = (struct entry*) malloc(sizeof(struct entry)); temp->lexeme = s; temp->val.class = t; temp->type = 0; temp->next_e = e; return temp; } struct field *new_field(double v) { struct field *temp; temp = (struct field*) malloc(sizeof(struct field)); temp->v1 = v; return temp; } struct tab *new_tab(int interface, struct tab *u) { struct tab *temp; temp = (struct tab*)malloc(sizeof(struct tab)); temp->count = 0; if (interface == 0 || interface == 1) temp->interface = interface; else { fprintf(inspect_file,"\nerror new_tab: parameter interface with value not in [0,1]"); temp->interface = 1; } temp->up = u; temp->down = NULL; if (u != NULL) { struct tabList *temp2; temp2 = (struct tabList*)malloc(sizeof(struct tabList)); temp2->acc = temp; temp2->next = u->down; u->down = temp2; } return temp; } struct meth *new_meth(char *nm, struct entry *c, struct entryList *ts, struct entry *t, struct tab *b, struct stmList *z) { struct meth *temp; temp = (struct meth*)malloc(sizeof(struct meth)); temp->name = nm; temp->class = c; temp->dom = ts; temp->cod = t; temp->block = b; temp->code = z; return temp; } struct methList *mcons(struct meth *h, struct methList *l) { if (h == NULL) { fprintf(inspect_file,"err: null argument in mcons\n"); return l; } struct methList *temp = (struct methList *)malloc(sizeof(struct methList)); temp->mpoint = h; temp->mseq = l; return temp; } void meth_reset(struct meth* the_meth, struct entry *class, struct entryList *dom, struct entry *im, struct stmList *code) { the_meth->class = class; the_meth->dom = dom; the_meth->cod = im; the_meth->code = code; } struct pair2 *new_pair2(struct entryList *ts, struct stmList *c) { struct pair2 *temp; temp = (struct pair2*)malloc(sizeof(struct pair2)); temp->ty = ts; temp->cc = c; return temp; } struct pair3 *new_pair3(int num, struct pair2 *p) { struct pair3 *temp; temp = (struct pair3*)malloc(sizeof(struct pair3)); temp->bval = num; temp->val = p; return temp; } struct funType *new_funType(struct entryList *ts, struct entry *t) { struct funType *temp; temp = (struct funType*)malloc(sizeof(struct funType)); temp->ty = ts; temp->cod = t; return temp; } struct sel *new_sel(int f, char *m, struct sup_pam *g, struct sel *p) { struct sel *temp; temp = (struct sel*)malloc(sizeof(struct sel)); temp->flag = f; temp->main = m; temp->pam = g; temp->seq = p; return temp; } struct entry *insertA(struct tab *t, char *s, struct rec* v) { int n = hash(s)%Nentry; t->count++; struct entry *temp = new_entryA(s,v,t->base[n]); t->base[n] = temp; return temp; } void resetA(struct entry *e, struct rec* v) { e->val.addr = v; } struct entry *insertF(struct tab *t, struct funType *v) { char *R; char *tempS = strdup(""); if (v != NULL) { struct entryList *cur = v->ty; if (cur != NULL) { if (cur->hd != NULL) tempS = strdup(cur->hd->lexeme); for(cur=cur->tl; cur != NULL; cur=cur->tl) { R = strcat(strdup(tempS),"."); free(tempS); tempS = R; if (cur->hd != NULL) { R = strcat(strdup(tempS),strdup(cur->hd->lexeme)); free(tempS); tempS = R; } } } R = strcat(strdup(tempS),"->"); free(tempS); tempS = R; if (v->cod != NULL) { R = strcat(strdup(tempS), strdup(v->cod->lexeme)); free(tempS); tempS = R; } else { R = strcat(strdup(tempS), "."); free(tempS); tempS = R; } } R = strdup(tempS); free(tempS); int n = hash(R)%Nentry; t->count++; struct entry *temp = new_entryF(R,v,t->base[n]); t->base[n] = temp; fprintf(inspect_file,"---insertF:%s %d\n", R, temp); return temp; } struct entry *insertT(struct tab *to, char *s, struct tab *t) { fprintf(inspect_file,"enter insertT\n"); int n = hash(s)%Nentry; to->count++; struct entry *temp = new_entryT(s,t,to->base[n]); to->base[n] = temp; return temp; } void resetT(struct entry *e, struct tab* t) { e->val.class = t; } struct entry *find0(struct tab *to, char *s) // rewrite compl. { int n = hash(s)%Nentry; struct entry *cur = NULL; struct tab *curTab; for(curTab=to; (curTab!=NULL) && (cur==NULL); curTab=curTab->up) { struct entry *temp = (curTab->base)[n]; for(cur = temp; cur!=NULL && (strcmp(cur->lexeme,s)!=0); cur = cur->next_e); } if (cur == NULL) { struct entry *temp = (MainTab->base)[n]; for(cur = temp; cur!=NULL && (strcmp(cur->lexeme,s)!=0); cur = cur->next_e); } if (cur == NULL) return undef; else return cur; } void showTab(FILE *out, struct tab *t, int indent) { fprintf(out, "tabella %d extends %d\n", t, t->up); showBlock(out, t->count, indent, t->base); struct tabList *temp; for(temp=t->down; temp!=NULL; temp=temp->next) showTab(out, temp->acc, (indent+10)%40); } void showValue(FILE *out, int indent, struct entry *e) { struct entry *temp; for(temp=e; temp!=NULL; temp=temp->next_e) { if(temp->type == 0) { struct tab *temptab=temp->val.class; if(temptab->count!=0) showTab(out,temptab,indent); } } } void showBlock(FILE *out, int num, int indent, struct entry *A[]) { fprintf(out, "tabella con %d membri e livello di annidamento %d\n", num, indent); int i; for(i=0; inext_e) { fprintf(out, "%s| %10s --> ", &disp, temp->lexeme); if ((temp->type == 0)||(temp->type == -2)) { fprintf(out, "%d\n", temp->val.class); continue; } if (temp->type == -1) { fprintf(out, "%s\n", "basic_type"); continue; } if (temp->type > 0) { showAddr(out, temp->val.addr); continue; } } } void showMeth(FILE *out, struct meth *m) { fprintf(out, "method: %s class = %s dom = ", m->name, m->class->lexeme); struct entryList *temp; for(temp = m->dom; temp != NULL; temp = temp->tl) { if (temp->hd != NULL) fprintf(out, "%s ", temp->hd->lexeme); else fprintf(out, "%s ", "VOID"); } fprintf(out, " cod = "); if (m->cod == NULL) fprintf(out, "VOID \n"); else fprintf(out, "%s \n", m->cod->lexeme); } void showMethList(FILE *out, struct methList *lista) { fprintf(out,"\n\n *************** list of the methods in the package **************\n"); struct methList *cur; for (cur = lista; cur != NULL; cur = cur->mseq) showMeth(out, cur->mpoint); } struct methList *mkMList(struct tab *myTab) // aggiunge anche i costruttori { struct methList *R = NULL; int i; for(i=0; ibase[i]; struct entry *cur; for(cur=x; cur!=NULL; cur=cur->next_e) { if((cur->type>0)&&(cur->val.addr->type==3)) R=mcons(cur->val.addr->data.mt,R); } } return R; } struct methListOfList *new_methListOfList(int n, struct meth *m, struct methListOfList *P) { struct methListOfList *u = malloc(sizeof(struct methListOfList)); u->n=n; u->vn=mcons(m,NULL); u->next=P; return u; } struct methListOfList *add_methListOfList(int n, struct meth *m, struct methListOfList *P) { if ((P == NULL)||(P->n > n)) return new_methListOfList(n,m,P); struct methListOfList *cur,*prev; prev = P; for(cur = P; cur != NULL; cur = cur->next) { if(cur->n < n) { prev = cur; continue; } if(cur->n == n) { cur->vn = mcons(m,cur->vn); return P; } prev->next = new_methListOfList(n,m,cur); return P; } prev->next = new_methListOfList(n,m,cur); return P; } int parNum(struct meth *m) { struct entryList *dm = m->dom; int R = 0; struct entryList *cur; for(cur=dm; cur!=NULL; cur=cur->tl) R++; return R; } struct methListOfList *toMethListOfList(struct tab *myTab) { struct methList *letMyList = mkMList(myTab); struct methListOfList *R = NULL; struct methList *cur; for(cur=letMyList;cur!=NULL;cur=cur->mseq) { struct meth *temp = cur->mpoint; R = add_methListOfList(parNum(temp),temp,R); } } void showMethL(struct methList *methL){ struct methList *cur; for(cur=methL; cur!=NULL; cur=cur->mseq) { printf("\nname = %s", cur->mpoint->name); } } void showMethLL(struct methListOfList *methLL){ struct methListOfList *cur; for(cur=methLL; cur!=NULL; cur=cur->next) { printf("\narity = %d", cur->n); showMethL(cur->vn); } } struct methList *filteroverloaded(struct methList *mL) { struct methList *R = NULL; struct methList *cur; for(cur=mL; cur!=NULL; cur=cur->mseq) {int ok=0; struct methList *temp; for(temp=mL; temp!=NULL; temp=temp->mseq) if((cur!=temp)&&(strcmp(cur->mpoint->name,temp->mpoint->name)==0)) ok=1; if (ok==0) R=mcons(cur->mpoint,R); } return R; } struct methList *filterApply(struct methList *mL) //remove constructors and overloaded { struct methList *R = NULL; struct methList *cur; for(cur=mL; cur!=NULL; cur=cur->mseq) { if ((cur->mpoint->cod != NULL) && (cur->mpoint->name != cur->mpoint->class->lexeme)) R=mcons(cur->mpoint,R); } return filteroverloaded(R); } struct methList *filterApplyS(struct methList *mL) { struct methList *R = NULL; struct methList *cur; for(cur=mL; cur!=NULL; cur=cur->mseq) { if (cur->mpoint->cod == NULL) R=mcons(cur->mpoint,R); } return filteroverloaded(R);; } //-------------------------------------- operatori di conversione: int_toString char conv_cifra(int i) //0<=i<=9 { if(i==0)return'0'; if(i==1)return'1'; if(i==2)return'2'; if(i==3)return'3'; if(i==4)return'4'; if(i==5)return'5'; if(i==6)return'6'; if(i==7)return'7'; if(i==8)return'8'; if(i==9)return'9'; return '*'; } int expT(int b, int e) { if (e == 0) return 1; int temp = b; int i; for(i = 2 ; i <= e ; i++) temp=temp*b; return temp; } char *toString(int i) { int k; for(k=1;expT(10,k)<=i;k++); char *r=malloc(k*sizeof(char)); int j; r[k]='\0'; int temp=i; for(j=1;j<=k;j++) { r[k-j] = conv_cifra(temp%10); temp=(temp/10); } return r; } //------------------------------- operatori di conversione: int_toString -- end char *concat(char *u, char *v) { char *t1 = strdup(u); char *t2 = strdup(v); int n = 1+strlen(t1)+strlen(t2); char *R = malloc(n*sizeof(char)); strcpy(R,t1); R = strcat(R,t2); } char *flatten(struct sup_pam *list) {// code translation rules: begin if (list == NULL) return ""; int n=1; struct sup_pam *cur; for(cur=list; cur!=NULL; cur=cur->tl) n+=strlen(cur->hd)+1; char *temp = malloc(n*sizeof(char)); temp = strcpy(temp,"("); for(cur=list; cur!=NULL; cur=cur->tl) { char *v = strdup(cur->hd); temp = concat(temp,v); if (cur->tl!=0)temp=concat(temp,","); }; temp = concat(temp,")"); return temp; } struct methList *filter_ApplyApplyS(struct methList *methLL, int index) {// index==0: means filterApply; index==0: means filterApplyS; if (index==0) return filterApply(methLL); else return filterApplyS(methLL); } void showAddr(FILE *out, struct rec* v) { fprintf(out, "%d\n", v); } void addType(struct entryList *v, struct entry *t) // to define ---- { } struct entryList *cons(struct entry *a, struct entryList *v) { struct entryList *temp = (struct entryList *)malloc(sizeof(struct entryList)); temp->hd = a; temp->tl = v; return temp; } struct sup_pam *consR(char *v, struct sup_pam *r) { struct sup_pam *temp = (struct sup_pam *)malloc(sizeof(struct sup_pam)); temp->hd = v; temp->tl = r; return temp; } void fileCopy(FILE *from, FILE *into) { char c; for (c=getc(from); c!= EOF; c=getc(from)) putc(c,into); } // ------------------------------------- //--------------------------------- main part: procedure void initState() { Object = (struct tab*) malloc(sizeof(struct tab)); Object->count = 0; Object->up = NULL; Object->down = NULL; SymTab = (struct tab*) malloc(sizeof(struct tab)); // allocazione tabella SymTab->count = 0; SymTab->up = Object; // for the table of the package SymTab->down = NULL; MainTab = SymTab; // MainTab is the table of the package Tobject = insertT(Object, "Object", Object); // type Object Tobject -> type = -2; // type Object Tinteger = insertT(Object,"Integer",new_tab(1,NULL)); Object = (struct tab*) malloc(sizeof(struct tab)); Object->count = 0; Object->up = NULL; Object->down = NULL; undef = insertA(Object,"UNKNOWN",NULL); //unit of objects undef -> type = -4; //tag of unit struct entry *temp; temp = insertA(Object, "System", new_rec_f(new_field(0))); temp = insertA(Object, "out", new_rec_f(new_field(0))); temp = insertA(Object, "println", new_rec_f(new_field(0))); temp = insertA(Object, "io", new_rec_f(new_field(0))); temp = insertA(Object, "java", new_rec_f(new_field(0))); temp = insertA(Object, "util", new_rec_f(new_field(0))); Tbool = insertA(Object, "boolean", NULL); Tbool->type = -1; // sets for a basic type Tbyte = insertA(Object, "byte", NULL); Tbyte->type = -1; Tchar = insertA(Object, "char", NULL); Tchar->type = -1; Tshort = insertA(Object, "short", NULL); Tshort->type = -1; Tint = insertA(Object, "int", NULL); Tint->type = -1; Tfloat = insertA(Object, "float", NULL); Tfloat->type = -1; Tlong = insertA(Object, "long", NULL); Tlong->type = -1; Tdouble = insertA(Object, "double", NULL); Tdouble->type = -1; Tvoid = insertA(Object, "void", NULL); Tvoid->type = -1; atomicFlag = 2; // default for nonclass identifier -- 0 for class identifier current_class = "Object"; OnOff = NULL; // stack is set to empty resetOff(); // for a new class traversal } char *emitApplyCall(struct sel *do1, struct sel *do2) { struct sel *val; for(val=do1; val->seq!=NULL; val=val->seq); val->seq = do2; char *exp = ""; struct sel *cur; for(cur=do1; cur!=NULL; cur=cur->seq) { fprintf(inspect_file,"ciclo enter %d\n",cur); int f = cur->flag; if (((f==0)||(f==6)||(f==7)) && (cur->pam != NULL)) { atomicFlag = 2; struct entry *temp = symlook(cur->main); if((temp!=NULL)&&(temp->type>0)) { struct entry *ty = temp->trueType; if((ty != NULL)&&(ty->type == -3)) //it's an m_param { // emit of: //"((ApplyClass)E(exp)).apply/S(main,new Object[]{(Ftype1)E(exp1)..,(Ftypek)E(expk)})" // ---------------------------------------------------------- begin // emit of "((ApplyClass)E(exp)).": ------------------------- begin // if exp is empty then "((ApplyClass)this)." if(f==7) { if(strlen(exp)==0) exp = "this"; else { fprintf(inspect_file,err1E3); exp = ""; } } exp = concat("((ApplyClass)",concat(exp,").")); // emit of "((ApplyClass)E(exp)).": ------------------------- end // emit of "new Object[]{(Ftype1)E(exp1)..,(Ftypek)E(expk):---- begin struct funType *tyType = ty->val.type; struct entry *tyTypeCod = tyType->cod; // always!=NULL struct entryList *tyTypeTy = tyType->ty; char *emitParList = ",new Object[]"; struct entryList *pointer; struct sup_pam *term = cur->pam; for(pointer=tyTypeTy; pointer!=NULL; pointer=pointer->tl) { if(term!=NULL) { char *emitType; if(pointer->hd->type == -3) emitType="String"; else emitType=pointer->hd->lexeme; char *emitPar=concat(",(",concat(emitType,concat(")",term->hd))); emitParList = concat(emitParList,emitPar); } else fprintf(err_file, err2E3); } // emit of "new Object[],(Ftype1)E(exp1)..,(Ftypek)E(expk)": --- end int voidCheck = 1; char *applyTerm = "ApplyS"; // m_param is a void method if(strcmp(tyTypeCod->lexeme,"void")!=0) { applyTerm = "Apply"; voidCheck = 0; } char *expTemp = concat(exp,concat(applyTerm,concat("(",cur->main))); // emit of "new Object[]{(Ftype1)E(exp1) ... ,(Ftypek)E(expk))}:---------------- begin if (strlen(emitParList)>13) { emitParList[13]='{'; emitParList = concat(emitParList,"}"); } else emitParList = concat(emitParList,"{}"); expTemp = concat(expTemp,concat(emitParList,")")); exp = expTemp; // emit of "((ApplyClass)E(exp)).(main ,(Ftype1)E(exp1) ... ,(Ftypek)E(expk))": ----- end if(voidCheck==0) { char *head = concat("(",concat(strdup(tyTypeCod->lexeme),")")); exp = concat("(",concat(head,concat(exp,")"))); } continue; } } } char *args = flatten(cur->pam); fprintf(inspect_file,"fammi vedere args: %s\n",args); // int n = strlen(exp)+strlen(cur->main)+strlen(args)+1; char *temp = exp; if ((f==0)||(f==6)) temp = strcat(temp,"."); temp = concat(temp,cur->main); temp = concat(temp,args); temp = concat(temp," "); exp = temp; }; return exp; } char *emitApplyDisp(struct methListOfList *methLL) { char *temp = strdup("private static int Dispatcher(String S){\n\tint pos = -1;\n"); int ipos = 0; struct methListOfList *cur; int apply; for (apply = 0; apply < 2; apply++) { for(cur=methLL; cur!=NULL; cur=cur->next) { struct methList *mL = filter_ApplyApplyS(cur->vn,apply); if(mL != NULL) { struct methList *curm; for(curm=mL; curm!=NULL; curm=curm->mseq) { char *methName = strdup(curm->mpoint->name); char *meth; if (ipos == 0) meth = concat(strdup("\tif(S.equals(\""),concat(methName,strdup("\")) pos = 0;\n"))); else { char *ap = strdup("pos = "); ap = strncat(ap,toString(ipos),2); // no more than 100 methods per class meth = concat(strdup("\telse if(S.equals(\""),concat(methName,concat(strdup("\")) "),concat(ap,strdup(";\n"))))); } temp = concat (temp, meth); ipos++; } } } } temp = concat(temp,"\treturn pos;\n}\n"); return temp; } char *emitApplyList(struct methListOfList *methLL) { char *temp=""; int ipos = 0; struct methListOfList *cur; if (methLL == NULL) fprintf(inspect_file,"tab vuoto\n"); int apply; char *fparam = strdup(",Object[]P) throws MethodNotFoundException{\n"); for (apply = 0; apply < 2; apply++) { char *tempn; if (apply == 0) tempn = concat("public Object Apply(String m",fparam); else tempn = concat("public void ApplyS(String m",fparam); char *applyTerm = strdup("\tint pos=Dispatcher(m);\n\tswitch(pos){\n"); for(cur=methLL; cur!=NULL; cur=cur->next) { struct methList *mL = filter_ApplyApplyS(cur->vn,apply); if(mL != NULL) { char *sbody = ""; struct methList *curm; for(curm=mL; curm!=NULL; curm=curm->mseq) { char *methName = strdup(curm->mpoint->name); char *ap = strdup("\t\t case "); ap = concat(ap,toString(ipos));// no more than 100 methods; char *meth1 = ap; char *meth3; if (apply == 0) meth3 = concat(": return ", methName); else meth3 = concat(": ", concat("{",methName)); // calculate aparam: "((type0)P[0],...,(typen-1)P[n-1])" ----------------- begin int n = cur->n; int i; struct entryList *tempCast; tempCast = curm->mpoint->dom; char *aparam=strdup("("); for(i=0;i1) aparam = concat(aparam,strdup(",")); char *type; if (tempCast->hd->type == -3) type = strdup("String"); else type = strdup(tempCast->hd->lexeme); char *ap = concat("(",concat(type,")")); tempCast = tempCast->tl; ap = concat(ap,strdup("P[")); ap = strncat(ap,toString(i),2);// no more than 100 parameters; aparam=concat(aparam,concat(ap,"]")); }; // -- add ")" to aparam: begin aparam = concat(aparam,")"); // -- add ")" to aparam: end - list of actuals completed // header of Apply is completed and added to tempn --------------- end // switch body: // "\t\tcase("meth_namei"): // return meth_namei((t0)pi[0]...(tn-1)pi[n-1])..." -- begin char *meth4 = concat(meth3,aparam); char *meth5 = concat(meth1,meth4); char *meths; if (apply == 0) meths = concat(meth5,";\n"); else meths = concat(meth5,"; break;}\n"); sbody = concat(sbody,meths); ipos++; } // sbody: "\t\tcase("meth_namei"): return meth_namei(pi[0]...pi[n-1])..." ---- end applyTerm = concat(applyTerm,sbody); } } applyTerm = concat(applyTerm,"\t\t default: throw new MethodNotFoundException();\n\t\t}\n}\n"); applyTerm = concat(strdup(tempn),applyTerm); temp = concat(temp,applyTerm); } return temp; } struct entry *symlook(char *s) { if (atomicFlag == 0) { return insertT(SymTab,s,new_tab(1,NULL)); //for classes or block env } if (atomicFlag == 4) { return insertT(SymTab,s,new_tab(0,NULL)); // for interfaces } if (atomicFlag == 1) // for generic fields { return insertA(SymTab,s,new_rec_f(new_field(0))); } if (atomicFlag == 3) // for methods { struct entry *var1 = insertA(SymTab,s, new_rec_m(new_meth(s,NULL,NULL,NULL,new_tab(1,SymTab),NULL))); return var1; } struct entry *sp = find0(SymTab,s); if (sp == NULL){ fprintf(err_file,"error line %d: %s not_declared\n",lineno,s); return insertA(SymTab,s,new_rec_f(new_field(0))); //forziamo gli identificatori } return sp; }/* symlook() */ warning(char *err1, char *err2){ if (yyerrflag !=0) return; fprintf(stderr,"%s: %s\n", err1, err2); } main(int argc, char *argv[]) { char *outfile; char *infile; extern FILE *yyin, *yyout; yyout = fopen(DEFAULT_OutFile,"w"); // ---- unused, here: classes and methods abstract syntax err_file = fopen("ERRFILE.txt","w"); // ---- syntactic errors inspect_file = fopen("CHECK.txt","w"); // ---- for internal uses: traslation trace // temporary = fopen("TEMPFILE.txt","w"); // ---- unused, here: code backpatching program = argv[0]; if(argc > 3) { fprintf(err_file,usage,program); exit(1); } if(argc > 1) { infile = argv[1]; yyin = fopen(infile,"r"); if (yyin == NULL) { fprintf(err_file, "%s: cannot open %s\n",program,infile); exit(1); } } if(argc > 2) { obj_file = fopen(argv[2],"w"); // ---- obj_file for the translated code } else obj_file = fopen("TARGET.txt","w"); if (yyout == NULL) { fprintf(err_file, "%s: cannot open %s\n",program,outfile); exit(1); } fprintf(obj_file,"// ************************************************************************************\n"); fprintf(obj_file,"// ***** This code is automatically generated by System H.00 *****\n"); fprintf(obj_file,"// ***** System H.00 is a prototype implementation of: *****\n"); fprintf(obj_file,"// ***** JavaM - Java extended with methods as parameters *****\n"); fprintf(obj_file,"// ***** Translation begin. Source file is: *****\n"); fprintf(obj_file,"// %-20.5s %+20.20s %+42.*s\n","*****",argv[1],5,"*****"); fprintf(obj_file,"// ***** *****\n"); fprintf(obj_file,"// ************************************************************************************\n"); initState(); fprintf(err_file,"argc: %d argomenti e programma %s \n", argc, program); yyparse(); /* parser reads from yyin and writes into yyout */ fprintf(yyout,"**************** Main Pack: ambiente classi dichiarate nel package ****************\n"); showTab(yyout, MainTab, 0); fprintf(inspect_file,"\n ***** codice generato: END *****\n"); fprintf(obj_file,"\n\n\n// ***** Translation end: made by\n// %s\n", program); fprintf(yyout,"\n\n**************** Object e le sottoclassi: le classi create ****************\n"); showTab(yyout, Object, 0); showMethList(yyout, mcollection); /* checks for premature EOF have to be added */ fclose(err_file); fclose(inspect_file); fclose(obj_file); fclose(yyin); fclose(yyout); return 0; }