lsd10.y
Description du code
Fichier Yacc du langage LSD010 Compilateur LSD010Code source ou contenu du fichier
Code Bison (lsd10.y) (759 lignes)
%{ /* * lsd10.y : lexical parsing file for Bison * Part of the compiler project for LSD10 language * Gaudry Stéphane * More information on http://www.gaudry.be/langages-yacc.html */ #include <stdio.h> #include <stdlib.h> #if(VERBOSE_LEVEL<=DEB_E) #include <errno.h> #endif #if(VERBOSE_LEVEL<=DEB_EXEC) #include <time.h> #endif #include <sys/types.h> #include <dirent.h> #include "common.h" #ifdef WIN32 #define FILE_SEPARATLEXICAL_OR "\\" #else #define FILE_SEPARATLEXICAL_OR "/" #endif extern int lexLinesCount; //extern int lexCharsLineCountBeforeToken; extern int lexTotalCharsCount; extern char* yytext; extern int *yylineno; extern FILE *yyin; /** * Position of a detected error */ DebugInfo *debugInfo; AstNode *rootNode; // to avoid 'implicit definition' int yylex(void); int yyerror(char *str); %} %union{ int nval; char *text; struct astNode *node; } %error-verbose %locations %token LEXICAL_BOOLEAN_TYPE LEXICAL_INTEGER_TYPE LEXICAL_VOID_TYPE LEXICAL_INSTACK_TYPE %token <nval> NUMBER %token LEXICAL_TRUE_VAL LEXICAL_FALSE_VAL %token LEXICAL_AND LEXICAL_OR LEXICAL_ANDLAZY LEXICAL_ORLAZY LEXICAL_NOT LEXICAL_EQUALS LEXICAL_LESS_EQUALS LEXICAL_LESS %token LEXICAL_AFFECTATION %token LEXICAL_PLUS LEXICAL_MINUS LEXICAL_MULT LEXICAL_DIV LEXICAL_MOD %token L_PARENTHESIS LSQUI_BRACKET LSQUA_BRACKET POINT RSQUA_BRACKET R_PARENTHESIS RSQUI_BRACKET %token LEXICAL_GET_OPS LEXICAL_ISEMPTY_OPS LEXICAL_WRITE_OPS LEXICAL_READ_OPS LEXICAL_PUT_OPS LEXICAL_RETURN_STMT %token LEXICAL_IF_STMT LEXICAL_ELSE_STMT LEXICAL_WHILE_STMT LEXICAL_FOR_STMT %token COLON SEMICOLON COMMA %token LEXICAL_VAR %token <text>ID %type <node> Prg Function Functions PostFixeFunction %type <node> ArgDeclaration ParamList ParamList_FunctionCall %type <node> FuncOrVar VarIds %type <node> Declarations Declaration %type <node> Statements Statement %type <node> iteration_while if_instruction iteration_for %type <node> LExpr RExpr %type <nval> FunctionType VarType %left LEXICAL_AND LEXICAL_OR LEXICAL_ANDLAZY LEXICAL_ORLAZY %right LEXICAL_NOT %left LEXICAL_EQUALS LEXICAL_LESS_EQUALS LEXICAL_LESS %left LEXICAL_PLUS LEXICAL_MINUS %left LEXICAL_MULT LEXICAL_DIV LEXICAL_MOD %start Prg %% Prg: Functions { rootNode=$1;//createASTNode(10,createASTNodeInfo("Root", NODE_TYPE_NOTHING, NO_VAL),$1,NULL); } ; Functions: {$$=NULL;} | Function Functions { #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"Functions node", __FILE__, __LINE__); #endif // Avoid building an unneeded node if($1==NULL && $2!=NULL) { $$=$2; } else if($2==NULL && $1!=NULL) { $$=$1; } else { $$=createASTNode(&@1,NODE_TYPE_FUNCTIONS, createASTNodeInfo("Functions", NODE_TYPE_NOTHING, NO_VAL), $2, $1); } } ; Function: FunctionType ID L_PARENTHESIS ParamList R_PARENTHESIS PostFixeFunction{ #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"Function node", __FILE__, __LINE__); #endif $$=createASTNode(&@2,NODE_TYPE_FUNCTION, createASTNodeInfo($2, $1, NO_VAL), $4, $6); } ; PostFixeFunction: LSQUI_BRACKET LSQUI_BRACKET Declarations RSQUI_BRACKET Statements RSQUI_BRACKET { #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"PostFixeFunction node", __FILE__, __LINE__); #endif // Avoid building an unneeded node if($3==NULL) { $$=$5==NULL?NULL:$5; } else if($5==NULL) { $$=$3; } else { $$=createASTNode(&yylloc,NODE_TYPE_CONTAINER, createASTNodeInfo("{{decl}statement}", NODE_TYPE_NOTHING, NO_VAL), $3, $5); } } ; Declarations: { $$=NULL; } | Declaration Declarations { #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"Declarations node", __FILE__, __LINE__); #endif // Avoid building an unneeded node if($2==NULL) { $$=$1; } else { $$=createASTNode(&yylloc,NODE_TYPE_DECLARATIONS, createASTNodeInfo("Declarations node", NODE_TYPE_NOTHING, NO_VAL), $1, $2); } } ; Declaration: LEXICAL_VOID_TYPE ID L_PARENTHESIS ParamList R_PARENTHESIS PostFixeFunction { /*void function*/ $$ = createASTNode(&@2,NODE_TYPE_FUNCTION, createASTNodeInfo($2, AST_VOID_VAR_TYPE, NO_VAL), $4, $6); //setNodeSubType($$, SUBFUNCTION); } | VarType ID FuncOrVar { if($3==NULL || $3->type==NODE_TYPE_VAR_DECL) { // multiple variables declarations like "integer i j;" // we must set the type for each variable AstNode *tempNode = $3; while(tempNode!=NULL) { //printf("\nVar ids: %s (on %s %d)\n", varNode->info->name, __FILE__, __LINE__); setComputedType(tempNode,$1); tempNode=tempNode->left; } $$=createASTNode(&yylloc,NODE_TYPE_VAR_DECL, createASTNodeInfo($2, $1, NO_VAL), $3, NULL); setComputedType($$,$1); } else { // function declaration $$ = createASTNode(&yylloc,NODE_TYPE_FUNCTION, createASTNodeInfo($2, $1, NO_VAL), $3->right, $3->left); setComputedType($$,$1); //setNodeSubType($$, SUBFUNCTION); free($3); } } ; FuncOrVar: L_PARENTHESIS ParamList R_PARENTHESIS PostFixeFunction { $$=createASTNode(&yylloc,NODE_DECL_PVAL, createASTNodeInfo("function", NODE_TYPE_NOTHING, NO_VAL), $2, $4); } | VarIds SEMICOLON { $$=$1; } ; VarIds: {$$=NULL;} | ID VarIds { $$=createASTNode(&yylloc,NODE_TYPE_VAR_DECL, createASTNodeInfo($1, NODE_TYPE_NOTHING, NO_VAL), $2, NULL); } ; FunctionType: LEXICAL_BOOLEAN_TYPE { $$=AST_BOOLEAN_VAR_TYPE; #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"FunctionType node : boolean", __FILE__, __LINE__); #endif } | LEXICAL_INTEGER_TYPE { $$=AST_INTEGER_VAR_TYPE; #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"FunctionType node : integer", __FILE__, __LINE__); #endif } | LEXICAL_VOID_TYPE { $$=AST_VOID_VAR_TYPE; #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"FunctionType node : void", __FILE__, __LINE__); #endif } ; ParamList: ArgDeclaration COMMA ParamList { $$=createASTNode(&yylloc,NODE_TYPE_PARAM_LIST, createASTNodeInfo(NO_NAME, NODE_TYPE_NOTHING, NO_VAL), $1, $3); } | ArgDeclaration { $$=createASTNode(&yylloc,NODE_TYPE_PARAM_LIST, createASTNodeInfo(NO_NAME, NODE_TYPE_NOTHING, NO_VAL), $1, NULL); } | {$$=NULL;} ; ArgDeclaration: LEXICAL_VAR VarType ID { #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"LEXICAL_VAR VarType ID node", __FILE__, __LINE__); #endif $$ = createASTNode(&yylloc,NODE_TYPE_PARAM_DECL, createASTNodeInfo($3, $2, NO_VAL), NULL, NULL); setNodeSubType($$, LEXICAL_VAR); } | VarType ID { #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"VarType ID node", __FILE__, __LINE__); #endif $$ = createASTNode(&yylloc,NODE_TYPE_PARAM_DECL, createASTNodeInfo($2, $1, NO_VAL), NULL, NULL); setNodeSubType($$, ID); setComputedType($$, $1); } ; VarType: LEXICAL_BOOLEAN_TYPE { $$=AST_BOOLEAN_VAR_TYPE; #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"VarType node : boolean", __FILE__, __LINE__); #endif } | LEXICAL_INTEGER_TYPE { $$=AST_INTEGER_VAR_TYPE; #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"VarType node : integer", __FILE__, __LINE__); #endif } | LEXICAL_INSTACK_TYPE { $$=AST_INSTACK_VAR_TYPE; #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"VarType node : instack", __FILE__, __LINE__); #endif } | LEXICAL_INTEGER_TYPE LSQUA_BRACKET NUMBER RSQUA_BRACKET{ $$=AST_INTEGER_ARRAY_VAR_TYPE; #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"VarType node : integer", __FILE__, __LINE__); #endif } | LEXICAL_BOOLEAN_TYPE LSQUA_BRACKET NUMBER RSQUA_BRACKET{ $$=AST_BOOLEAN_ARRAY_VAR_TYPE; #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"VarType node : integer", __FILE__, __LINE__); #endif } ; RExpr: LEXICAL_NOT RExpr { $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_BOOLEAN_VAR_TYPE, NO_VAL),NULL, $2); setNodeSubType($$, LEXICAL_NOT); } | RExpr LEXICAL_AND RExpr { $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_BOOLEAN_VAR_TYPE, NO_VAL),$1, $3); setNodeSubType($$, LEXICAL_AND); } | RExpr LEXICAL_OR RExpr { $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_BOOLEAN_VAR_TYPE, NO_VAL),$1, $3); setNodeSubType($$, LEXICAL_OR); } | RExpr LEXICAL_ANDLAZY RExpr { $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_BOOLEAN_VAR_TYPE, NO_VAL),$1, $3); setNodeSubType($$, LEXICAL_ANDLAZY); } | RExpr LEXICAL_ORLAZY RExpr { $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_BOOLEAN_VAR_TYPE, NO_VAL),$1, $3); setNodeSubType($$, LEXICAL_ORLAZY); } | LEXICAL_TRUE_VAL { $$=createASTNode(&yylloc,LEXICAL_TRUE_VAL, createASTNodeInfo(NO_NAME, AST_BOOLEAN_VAR_TYPE, NO_VAL),NULL, NULL); setNodeSubType($$, LEXICAL_TRUE_VAL); } | LEXICAL_FALSE_VAL { $$=createASTNode(&yylloc,LEXICAL_FALSE_VAL, createASTNodeInfo(NO_NAME, AST_BOOLEAN_VAR_TYPE, NO_VAL),NULL, NULL); setNodeSubType($$, LEXICAL_FALSE_VAL); } | LEXICAL_ISEMPTY_OPS L_PARENTHESIS ID R_PARENTHESIS { $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_BOOLEAN_VAR_TYPE, NO_VAL), NULL, createASTNode(&yylloc,NODE_TYPE_ID, createASTNodeInfo($3, NODE_TYPE_TODO, NO_VAL),NULL, NULL) ); setNodeSubType($$, LEXICAL_ISEMPTY_OPS); } | LEXICAL_GET_OPS L_PARENTHESIS ID R_PARENTHESIS { $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_INTEGER_VAR_TYPE, NO_VAL), NULL, createASTNode(&yylloc,NODE_TYPE_ID, createASTNodeInfo($3, NODE_TYPE_TODO, NO_VAL),NULL, NULL) ); setNodeSubType($$, LEXICAL_GET_OPS); } | RExpr LEXICAL_EQUALS RExpr { #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"=", __FILE__, __LINE__); #endif $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_BOOLEAN_VAR_TYPE, NO_VAL),$1, $3); setNodeSubType($$, LEXICAL_EQUALS); } | RExpr LEXICAL_LESS_EQUALS RExpr { $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_BOOLEAN_VAR_TYPE, NO_VAL),$1, $3); setNodeSubType($$, LEXICAL_LESS_EQUALS); #if(VERBOSE_LEVEL<=DEB_Y) //printf(";\ttest subtype %d",$$->subtype); printMsg(DEB_Y,"<=", __FILE__, __LINE__); #endif } | RExpr LEXICAL_LESS RExpr { #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"<", __FILE__, __LINE__); #endif $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_BOOLEAN_VAR_TYPE, NO_VAL),$1, $3); setNodeSubType($$, LEXICAL_LESS); } | RExpr LEXICAL_PLUS RExpr { #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"+", __FILE__, __LINE__); #endif $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_INTEGER_VAR_TYPE, NO_VAL),$1, $3); setNodeSubType($$, LEXICAL_PLUS); } | RExpr LEXICAL_MINUS RExpr{ #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"-", __FILE__, __LINE__); #endif $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_INTEGER_VAR_TYPE, NO_VAL),$1, $3); setNodeSubType($$, LEXICAL_MINUS); } | RExpr LEXICAL_MULT RExpr { #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"*", __FILE__, __LINE__); #endif $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_INTEGER_VAR_TYPE, NO_VAL),$1, $3); setNodeSubType($$, LEXICAL_MULT); } | RExpr LEXICAL_DIV RExpr { #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"LEXICAL_DIV", __FILE__, __LINE__); #endif $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_INTEGER_VAR_TYPE, NO_VAL),$1, $3); setNodeSubType($$, LEXICAL_DIV); } | RExpr LEXICAL_MOD RExpr { #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"LEXICAL_MOD", __FILE__, __LINE__); #endif $$=createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, AST_INTEGER_VAR_TYPE, NO_VAL),$1, $3); setNodeSubType($$, LEXICAL_MOD); } | L_PARENTHESIS RExpr R_PARENTHESIS { #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"(RExpr)", __FILE__, __LINE__); #endif $$=$2;//createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, NODE_TYPE_TODO, NO_VAL),NULL, $2); } | LExpr { #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"LExpr", __FILE__, __LINE__); #endif $$=$1;//createASTNode(&yylloc,NODE_TYPE_REXP, createASTNodeInfo(NO_NAME, NODE_TYPE_TODO, NO_VAL),$1, NULL); } | ID L_PARENTHESIS ParamList_FunctionCall R_PARENTHESIS { #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"Function call with parameters", __FILE__, __LINE__); #endif $$=createASTNode(&yylloc,NODE_TYPE_FUNCTION_CALL, createASTNodeInfo($1, NODE_TYPE_TODO, NO_VAL),$3, NULL); } | ID L_PARENTHESIS R_PARENTHESIS { #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"Function call without parameters", __FILE__, __LINE__); #endif $$=createASTNode(&yylloc,NODE_TYPE_FUNCTION_CALL, createASTNodeInfo($1, NODE_TYPE_TODO, NO_VAL),NULL, NULL); } | NUMBER { $$=createASTNode(&yylloc,NUMBER, createASTNodeInfo("CONSTANT, NUMBER", AST_INTEGER_VAR_TYPE, $1),NULL, NULL); } | LEXICAL_MINUS NUMBER { $$=createASTNode(&yylloc,NUMBER, createASTNodeInfo("CONSTANT, NEGATIVE NUMBER", AST_INTEGER_VAR_TYPE, 0-$2),NULL, NULL); } // | Statement { // $$=$1; // } ; LExpr: ID { #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"ID node", __FILE__, __LINE__); #endif $$=createASTNode(&yylloc,NODE_TYPE_ID, createASTNodeInfo($1, NODE_TYPE_NOTHING, NO_VAL),NULL, NULL); } | ID LSQUA_BRACKET RExpr RSQUA_BRACKET { $$=createASTNode(&yylloc,NODE_TYPE_ID,createASTNodeInfo($1, NODE_TYPE_NOTHING, NO_VAL),$3,NULL); setNodeSubType($$, LEXICAL_INSTACK_TYPE); } ; ParamList_FunctionCall: RExpr COMMA ParamList_FunctionCall { $$=createASTNode(&yylloc,NODE_TYPE_PARAM_LIST, createASTNodeInfo(NO_NAME, NODE_TYPE_NOTHING, NO_VAL),$1, $3); } | RExpr { $$=$1; setNodeType($$, NODE_TYPE_PARAM); } ; Statements: Statement Statements{ #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"Statements node", __FILE__, __LINE__); #endif // Avoid building an unneeded node if($2==NULL) { $$=$1; } else { $$=createASTNode(&yylloc,NODE_TYPE_FUNCTION_BODY, createASTNodeInfo("Statements node", NODE_TYPE_TODO, NO_VAL),$1, $2); } } | { $$=NULL;} ; Statement: SEMICOLON { #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"Statement : ';'", __FILE__, __LINE__); #endif $$=NULL; } | RExpr SEMICOLON { #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"Statement : 'RExpr;'", __FILE__, __LINE__); #endif $$=$1; } | LExpr LEXICAL_AFFECTATION RExpr SEMICOLON { $$=createASTNode(&yylloc,NODE_TYPE_STATEMENT, createASTNodeInfo("Statement : 'LExpr = RExpr;'", NODE_TYPE_CHECK, NO_VAL),$1, $3); setNodeSubType($$, LEXICAL_AFFECTATION); } | if_instruction { #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"Statement : 'if'", __FILE__, __LINE__); #endif $$=$1;//createASTNode(&yylloc,NODE_TYPE_STATEMENT, createASTNodeInfo("Statement : 'if'", NODE_TYPE_NOTHING, NO_VAL),$1, NULL); } | iteration_while { #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"Statement : 'while'", __FILE__, __LINE__); #endif $$=$1; } | iteration_for { #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"Statement : 'for'", __FILE__, __LINE__); #endif $$=$1; } | LEXICAL_WRITE_OPS L_PARENTHESIS RExpr R_PARENTHESIS SEMICOLON { #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"Statement : 'WRITE (RExpr);'", __FILE__, __LINE__); #endif $$=createASTNode(&yylloc,LEXICAL_WRITE_OPS, createASTNodeInfo("Statement : 'WRITE (RExpr);'", AST_INTEGER_VAR_TYPE, NO_VAL),NULL, $3); } | LEXICAL_READ_OPS L_PARENTHESIS LExpr R_PARENTHESIS SEMICOLON { #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"Statement : 'READ (LExpr);'", __FILE__, __LINE__); #endif $$=createASTNode(&yylloc,LEXICAL_READ_OPS, createASTNodeInfo("Statement : 'READ (LExpr);'", AST_INTEGER_VAR_TYPE, NO_VAL),NULL, $3); } | LEXICAL_PUT_OPS L_PARENTHESIS ID COMMA RExpr R_PARENTHESIS SEMICOLON { #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"Statement : 'PUT (ID, RExpr);'", __FILE__, __LINE__); #endif $$=createASTNode(&yylloc, LEXICAL_PUT_OPS, createASTNodeInfo("Statement : 'PUT;'", NODE_TYPE_NOTHING, NO_VAL), createASTNode(&yylloc,NODE_TYPE_ID, createASTNodeInfo($3, NODE_TYPE_NOTHING, NO_VAL),NULL, NULL), $5 ); } | LEXICAL_RETURN_STMT L_PARENTHESIS RExpr R_PARENTHESIS SEMICOLON { #if(VERBOSE_LEVEL<=DEB_Y) printMsg(DEB_Y,"Statement : 'LEXICAL_RETURN_STMT(RExpr);'", __FILE__, __LINE__); #endif $$=createASTNode(&yylloc,LEXICAL_RETURN_STMT, createASTNodeInfo("Statement : 'LEXICAL_RETURN_STMT(RExpr);'", NODE_TYPE_NOTHING, NO_VAL),NULL, $3); } ; iteration_for: LEXICAL_FOR_STMT L_PARENTHESIS Statements COLON RExpr COLON Statements R_PARENTHESIS LSQUI_BRACKET Statements RSQUI_BRACKET { AstNode *forBoundariesNode = createASTNode(&yylloc,NODE_TYPE_CONTAINER,createASTNodeInfo(NO_NAME, NODE_TYPE_NOTHING, NO_VAL),$3,$7); AstNode *forNode = createASTNode(&yylloc,NODE_TYPE_CONTAINER,createASTNodeInfo(NO_NAME, NODE_TYPE_NOTHING, NO_VAL),forBoundariesNode, $10); //AstNode *forConditionNode = createASTNode(&yylloc,NODE_TYPE_REXP,createASTNodeInfo(NO_NAME, NODE_TYPE_NOTHING, NO_VAL),$5,NULL); $$ = createASTNode(&yylloc,NODE_TYPE_STATEMENT,createASTNodeInfo(NO_NAME, NODE_TYPE_NOTHING, NO_VAL), $5, forNode ); setNodeSubType($$, LEXICAL_FOR_STMT); } ; iteration_while: LEXICAL_WHILE_STMT L_PARENTHESIS RExpr R_PARENTHESIS LSQUI_BRACKET Statements RSQUI_BRACKET { $$=createASTNode(&yylloc,NODE_TYPE_STATEMENT,createASTNodeInfo("while(RExpr){Statement}", NODE_TYPE_NOTHING, NO_VAL),$3, $6); setNodeSubType($$, LEXICAL_WHILE_STMT); } ; if_instruction: LEXICAL_IF_STMT L_PARENTHESIS RExpr R_PARENTHESIS LSQUI_BRACKET Statements RSQUI_BRACKET LEXICAL_ELSE_STMT LSQUI_BRACKET Statements RSQUI_BRACKET { AstNode *ifNode = $6; AstNode *elseNode = $10; $$=createASTNode(&yylloc, NODE_TYPE_STATEMENT, createASTNodeInfo("if(RExpr){Statement}else{Statement}", NODE_TYPE_NOTHING, NO_VAL), $3, createASTNode(&yylloc, NODE_TYPE_CONTAINER, createASTNodeInfo(NO_NAME, NODE_TYPE_NOTHING, NO_VAL), ifNode, elseNode ) ); setNodeSubType($$, AST_IF_ELSE_STMT); } | LEXICAL_IF_STMT L_PARENTHESIS RExpr R_PARENTHESIS LSQUI_BRACKET Statements RSQUI_BRACKET { $$=createASTNode(&yylloc,NODE_TYPE_STATEMENT,createASTNodeInfo("if(RExpr){Statement}", NODE_TYPE_NOTHING, NO_VAL),$3, $6); setNodeSubType($$, LEXICAL_IF_STMT); } ; %% void finalizeYacc() { #if(SYMTABLE_PRINT_REQUESTED==1 || VERBOSE_LEVEL<=DEB_I) printSymbolsTableFooter(); #endif #if(VERBOSE_LEVEL<=DEB_EXEC) printMsg(DEB_EXEC,"Cleaning memory...", __FILE__, __LINE__); #endif // finalizeSymbolsTable MUST be called BELEXICAL_FOR_STMTE finalizeAST to avoid double free or corruption finalizeSymbolsTable(); finalizeAST(); // if(psnBeforeToken!=NULL) // { // free(psnBeforeToken); // } // if(psnAfterToken!=NULL) // { // free(psnAfterToken); // } yylex_destroy(); #if(VERBOSE_LEVEL<=DEB_EXEC) printMsg(DEB_EXEC,"...OK Memory cleaned\n;\n;", __FILE__, __LINE__); #endif } int testFile(char *path) { #if(VERBOSE_LEVEL<=DEB_EXEC) time_t startTime = time(NULL); printf(";****************************************************************************************"); printMsg(DEB_EXEC,"Creating Symbols Table",__FILE__, __LINE__); #endif initializeSymbolsTable(); #if(SYMTABLE_PRINT_REQUESTED==1) printSymbolsTableHeader(); #endif #if(SYMTABLE_PRINT_REQUESTED!=1 && VERBOSE_LEVEL<=DEB_EXEC) printMsg(DEB_W,"Print Symbols table not requested (use DEB_I level minimum to print it)", __FILE__, __LINE__); #endif if(path==NULL || !(yyin=fopen(path,"r"))) { #if(VERBOSE_LEVEL<=DEB_EXEC) printMsg(DEB_EXEC,"Using Test file...false", __FILE__, __LINE__); printMsg(DEB_E, (char *)strerror(errno), __FILE__, __LINE__); printMsg(DEB_EXEC,"Calling yyparse()", __FILE__, __LINE__); #endif yyparse(); } else { #if(VERBOSE_LEVEL<=DEB_EXEC) printMsg(DEB_EXEC,"Using Test file...true", __FILE__, __LINE__); printf("; Parsing %s file...", path); printMsg(DEB_EXEC,"Calling yyparse()", __FILE__, __LINE__); #endif yyparse();/*retourne un booleen?*/ fclose(yyin); } #if(VERBOSE_LEVEL<=DEB_EXEC) printMsg(DEB_EXEC,"End of yyparse execution;", __FILE__, __LINE__); #endif #if(AST_PRINT_REQUESTED==1) printTree(); #endif #if(AST_PRINT_REQUESTED!=1 && VERBOSE_LEVEL<=DEB_EXEC) printMsg(DEB_W,"Print tree not requested (use DEB_I level minimum to print it)", __FILE__, __LINE__); #endif checkAST(); #if(AST_IMAGE_REQUESTED!=0) printGraph(); #endif #if(VERBOSE_LEVEL<=DEB_EXEC && PCODE_GENERATION_BYPASS) printMsg(DEB_EXEC,"P-code generation not requested.", __FILE__, __LINE__); #endif #if(!PCODE_GENERATION_BYPASS) #if(VERBOSE_LEVEL<=DEB_EXEC) printMsg(DEB_EXEC,"Generating p-code...", __FILE__, __LINE__); #endif generatePCode(); #if(VERBOSE_LEVEL<=DEB_EXEC) printMsg(DEB_EXEC,"...OK P-code generated;", __FILE__, __LINE__); #endif #endif #if(VAR_USAGE_REPORT_REQUESTED) printSymbolsUsage(); #endif finalizeYacc(); #if(VERBOSE_LEVEL<=DEB_EXEC) time_t endTime = time(NULL); char str[1024];//todo: minimize length sprintf( str, "Parsing started at %s;\t%d lines %d chars parsed in %g seconds\n;\tVerbose set on \"%s\" level", asctime(localtime(&startTime)), lexLinesCount, lexTotalCharsCount, difftime(endTime, startTime), debugLevelToString(VERBOSE_LEVEL) ); printMsg(DEB_EXEC,str, __FILE__, __LINE__); #endif //fprintf(stderr,"OK\n"); return EXIT_SUCCESS; } int main() { DIR *dir = NULL; struct dirent *file = NULL; char *path="tests"; #if(VERBOSE_LEVEL<=DEB_EXEC) printMsg(DEB_EXEC,"\n;\n;\tLSD010 Compiler [SSHD09]\n;\n;", __FILE__, __LINE__); #endif if((dir = opendir(path)) == NULL) { testFile(NULL); } else { char *filePath; while((file = readdir(dir)) != NULL) { if(strcmp(file->d_name, ".") && strcmp(file->d_name, "..")) { filePath = malloc(strlen(path) + strlen(file->d_name) + 2); sprintf(filePath, "%s%s%s", path, FILE_SEPARATLEXICAL_OR, file->d_name); //printf("\n; Opening %s file...", filePath); if(testFile(filePath) != EXIT_SUCCESS) { return EXIT_FAILURE; } } } closedir(dir); free(filePath); } #if(VERBOSE_LEVEL<=DEB_EXEC) printMsg(DEB_EXEC,"That's All Folks!", __FILE__, __LINE__); #endif fprintf(stderr,"OK\n"); return EXIT_SUCCESS; } int yyerror(char *str) { fprintf(stderr,"KO\n"); if(yytext!=NULL) { fprintf(stderr,";\n;\tError : \"%s\" On parsed code, Line %d : UNRECOGNISED '%s'\n\n", str, lexLinesCount, yytext); }else if(debugInfo!=NULL) { fprintf( stderr, ";\n;\tError : \"%s\" On %s, Line %d col %d\n\n", str, debugInfo->file, debugInfo->line, debugInfo->linePsn ); } // else if(lexLinesCount>0) // { // fprintf(stderr,";\n;\tError : \"%s\" On parsed code, Line %d\n\n", str, lexLinesCount); // } else { fprintf(stderr,";\n;\tError : \"%s\"\n\n", str); } finalizeYacc(); //failure for the parsed code, but success for the compiler (it must stop here) exit(EXIT_SUCCESS); }
Autres extraits de codes en Bison
- lsd10.y Fichier Yacc du langage LSD010 Compilateur LSD010
- Tous les extraits
Version en cache
22/12/2024 18:31:29 Cette version de la page est en cache (à la date du 22/12/2024 18:31:29) afin d'accélérer le traitement. Vous pouvez activer le mode utilisateur dans le menu en haut pour afficher la dernère version de la page.Document créé le 05/10/2009, dernière modification le 28/10/2018
Source du document imprimé : https://www.gaudry.be/sniplet-rf-lsd010/project/source/lsd10.y.html
L'infobrol est un site personnel dont le contenu n'engage que moi. Le texte est mis à disposition sous licence CreativeCommons(BY-NC-SA). Plus d'info sur les conditions d'utilisation et sur l'auteur.