ast.c
Description du code
Arbre syntaxique abstrait Compilateur LSD010Code source ou contenu du fichier
Code c (ast.c) (1062 lignes)
/* * ast.c : generation of an Abstract Syntaxic Tree, * and LSD10 constraints checks (data types, etc.). * Part of the compiler project for LSD10 language * Gaudry Stéphane * More information on http://www.gaudry.be/langages-analyse-syntaxique-ast.html */ #include <stdio.h> #include <stdlib.h> #include <string.h> #if(VERBOSE_LEVEL<=DEB_E) #include <errno.h> #endif #include "common.h" /* * ********************************************************** * Internal business implementations * ********************************************************** */ extern int lexLinesCount; extern char* yytext; extern int *yylineno; extern AstNode *rootNode; /* * counter for unique names */ int nameIncrementor=0; /** * main function node * allows to detect if the only one valid main function has been found before * and allows to get the main node without a new search */ AstNode *mainNode=NULL; /** * Never use this out of internal ast functions */ #define AST_TODO 21378 /** * Generates a human readable string for a type error */ char* typeFailureToString(int found, int expected, AstNode *checkedNode, char *file, int line) { char errorStr[1024];//todo: minimize length char *str = errorStr; if(checkedNode->type==NODE_TYPE_REXP) { str, "Wrong type for %s operation : \"%s\"(%d) expected, but \"%s\"(%d) found (compiler %s,%d)", typeToString(checkedNode->subtype), typeToString(expected), expected, typeToString(found), found, file, line ); } else { str, "Type check failure : \"%s\"(%d) expected, but \"%s\"(%d) found for %s (compiler %s,%d)", typeToString(expected), expected, typeToString(found), found, checkedNode->info->name, file, line ); } return str; } /** * Checks if the two given types are the same, and * triggers a Yacc custom error if they are not equals */ void checkType(int found, int expected, AstNode *checkedNode, char *file, int line) { if(found!=NODE_TYPE_NOTHING && found!=expected) { if( (found==AST_INTEGER_ARRAY_VAR_TYPE && expected==AST_INTEGER_VAR_TYPE) ||(found==AST_INTEGER_VAR_TYPE && expected==AST_INTEGER_ARRAY_VAR_TYPE) ||(found==AST_BOOLEAN_ARRAY_VAR_TYPE && expected==AST_BOOLEAN_VAR_TYPE) ||(found==AST_BOOLEAN_VAR_TYPE && expected==AST_BOOLEAN_ARRAY_VAR_TYPE) ) { return; } onError(typeFailureToString(found, expected, checkedNode, file, line), __FILE__, __LINE__, checkedNode); } } /** * Calls methods on the table of symbols to get the type of a given node (checkedNode) * Sets also the computed type to avoid further type checks * Pre-condition : table may not be null */ int getTypeWrapper(AstNode *checkedNode) { if(!isSymbolsTableAvailable()) { onError("Table of Symbols must not be NULL", __FILE__, __LINE__, checkedNode); //Failure of the compiler behavior, independent of the parsed code } int type = NODE_TYPE_NOTHING; if(checkedNode!=NULL){ #if(VERBOSE_LEVEL<=DEB_AST) ";\n\tgetTypeWrapper check for %15s (line %d, col %d) = %15s (%d), computed type= %s(%d) (compiler %s,%d)", checkedNode->info->name, checkedNode->debug->line, checkedNode->debug->linePsn, typeToString(checkedNode->type), checkedNode->type, typeToString(checkedNode->info->computedType), checkedNode->info->computedType, __FILE__, __LINE__ ); #endif if(/*checkedNode->info!=NULL && */checkedNode->info->computedType!=AST_TODO) { //the node type is already computed, no need to ask for it return checkedNode->info->computedType; } switch(checkedNode->type) { case LEXICAL_TRUE_VAL: case LEXICAL_FALSE_VAL: case NUMBER: case LEXICAL_WRITE_OPS: case LEXICAL_READ_OPS: // if(checkedNode->info!=NULL) // { // Pre defined types, no need to check type=checkedNode->info->type; // } break; default: // if(checkedNode->info!=NULL) // { switch(checkedNode->subtype) { case LEXICAL_EQUALS: case LEXICAL_PLUS: case LEXICAL_MINUS: case LEXICAL_MULT: case LEXICAL_MOD: case LEXICAL_DIV: case LEXICAL_LESS_EQUALS: case LEXICAL_LESS: case LEXICAL_AND: case LEXICAL_OR: case LEXICAL_ANDLAZY: case LEXICAL_ORLAZY: case LEXICAL_NOT: case LEXICAL_ISEMPTY_OPS: case LEXICAL_GET_OPS: type=checkedNode->info->type; break; default: { AstNode *declarationNode = getDeclaration(checkedNode); type = declarationNode->info->type; #if(VERBOSE_LEVEL<=DEB_AST) ";\n;\tgetType result for %s %s [%p], declaration : \"%s\"[%p] (%s type) (compiler %s,%d)\n", typeToString(type), checkedNode->info->name, checkedNode, declarationNode->info->name, declarationNode, typeToString(declarationNode->type), __FILE__, __LINE__ ); #endif } break; } // } break; } if(type==NODE_TYPE_NOTHING || type==NODE_TYPE_TODO) { #if(VERBOSE_LEVEL<=DEB_AST) printf(";\tSearch on left for \"%40s\" (%20s) type...\n", checkedNode->info->name, typeToString(checkedNode->type)); #endif type=getTypeWrapper(checkedNode->left); } if(type==NODE_TYPE_NOTHING || type==NODE_TYPE_TODO) { #if(VERBOSE_LEVEL<=DEB_AST) printf(";\tSearch on right for \"%40s\" (%20s) type...\n", checkedNode->info->name, typeToString(checkedNode->type)); #endif type=getTypeWrapper(checkedNode->right); } #if(VERBOSE_LEVEL<=DEB_AST) ";\n;\ttype of \"%s\" (%s) is %s... on %s line %d (compiler %s,%d)\n;\n", checkedNode->info->name, typeToString(checkedNode->type), typeToString(type), checkedNode->debug->file, checkedNode->debug->line, __FILE__, __LINE__ ); #endif // if(type == NODE_TYPE_NOTHING) // { // char errorStr[1024];//todo: minimize length // sprintf( // errorStr, // "Undeclared item \"%s\" (compiler %s,%d)", // checkedNode->info->name, // __FILE__, // __LINE__ // ); // onError(errorStr, __FILE__, __LINE__, checkedNode); // //failure for the parsed code, but success for the compiler (it must stop here) // exit(EXIT_SUCCESS); // } // else // { checkedNode->info->computedType = type; // } } return type; } /** * Checks if a node has the right type */ void checkOperationTypes(AstNode *operationNode) { //allowed type is the operand(s) type, not operator type int allowedType = NODE_TYPE_NOTHING; switch(operationNode->subtype) { case LEXICAL_PLUS: case LEXICAL_MULT: case LEXICAL_MOD: case LEXICAL_DIV: allowedType=AST_INTEGER_VAR_TYPE;//checkedNode->info->type; break; case LEXICAL_AND: case LEXICAL_OR: case LEXICAL_ANDLAZY: case LEXICAL_ORLAZY: allowedType=AST_BOOLEAN_VAR_TYPE;//checkedNode->info->type; break; case LEXICAL_NOT: allowedType=NODE_TYPE_NOTHING; checkType(getTypeWrapper(operationNode->right), AST_BOOLEAN_VAR_TYPE, operationNode, __FILE__, __LINE__); break; case LEXICAL_EQUALS: allowedType=NODE_TYPE_NOTHING; checkType(getTypeWrapper(operationNode->left), getTypeWrapper(operationNode->right), operationNode, __FILE__, __LINE__); break; case LEXICAL_LESS_EQUALS: case LEXICAL_LESS: allowedType=AST_INTEGER_VAR_TYPE; break; case LEXICAL_ISEMPTY_OPS: case LEXICAL_GET_OPS: allowedType=NODE_TYPE_NOTHING; checkType(getTypeWrapper(operationNode->right), AST_INSTACK_VAR_TYPE, operationNode, __FILE__, __LINE__); break; } if(allowedType!=NODE_TYPE_NOTHING) { checkType(getTypeWrapper(operationNode->right), allowedType, operationNode, __FILE__, __LINE__); checkType(getTypeWrapper(operationNode->left), allowedType, operationNode, __FILE__, __LINE__); } } /** * Initialize the first return statement found into the function. * todo : use a pointer to the next statement to manage a list of return statements found into a same function * pre-conditions: node type is LEXICAL_RETURN_STMT constant * node is not null */ void addReturnStatement(AstNode *returnNode) { //if(returnNode->type!=LEXICAL_RETURN_STMT)return; int type = getTypeWrapper(returnNode->right); AstNode *functionNode = (AstNode *)scopeHelperGetCurrentFunction(); if(functionNode!=NULL) { // this is needed by the specification of LSD10 checkType( type, functionNode->info->type, returnNode, __FILE__, __LINE__ ); returnNode->info->type=functionNode->info->type; returnNode->info->computedType=returnNode->info->type; // this is only for increase speed of further tests functionNode->info->returnStatement = returnNode; } } /** * Checks (the list of ->not yet) return statement(s) of a given function node. * todo : implement the list check * pre-conditions: node type is NODE_TYPE_FUNCTION constant * node is not null * checkTreeTypes has been called on the children of * this node before calling this, to set the return statements */ void checkReturnStatement(AstNode *functionNode) { //if(node->type!=NODE_TYPE_FUNCTION)return; switch(functionNode->info->type) { case AST_VOID_VAR_TYPE: if(functionNode->info->returnStatement!=NULL) { char errorStr[1024];//todo: minimize length errorStr, "Illegal return statement line %d col %d found into void %s function line %d col %d (compiler %s,%d)", functionNode->info->returnStatement->debug->line, functionNode->info->returnStatement->debug->linePsn, functionNode->info->name, functionNode->debug->line, functionNode->debug->linePsn, __FILE__, __LINE__ ); onError(errorStr, __FILE__, __LINE__, functionNode); } break; case AST_INTEGER_VAR_TYPE: case AST_BOOLEAN_VAR_TYPE: #if AST_RETURN_CHECK_REQUESTED==1 // this is not needed by the specification of LSD10 // LSD10 doesn't require the static check of a return existence into a function if(functionNode->info->returnStatement==NULL) { char errorStr[1024];//todo: minimize length errorStr, "Return statement not found for %s function line %d col %d, expected %s type (compiler %s,%d)", functionNode->info->name, functionNode->debug->line, functionNode->debug->linePsn, typeToString(functionNode->info->type), __FILE__, __LINE__ ); onError(errorStr, __FILE__, __LINE__, functionNode); } #endif break; } } /** * Sets the mainNode and returns an error if we detect another main function */ void checkMainFunction(AstNode *node) { if(mainNode==NULL) { if(isMainSignature(node)) { mainNode=node; } else { char errorStr[1024];//todo: minimize length errorStr, "Main function is not the last one (%s detected line %d col %d) (compiler %s,%d)", node->info->name, node->debug->line, node->debug->linePsn, __FILE__, __LINE__ ); onError(errorStr, __FILE__, __LINE__, node); } } // if(isMainSignature(node)) // { // mainNode=node; // AstNode *nodeToCheck = node->parent; // if(nodeToCheck!=NULL) // { // nodeToCheck = nodeToCheck->left; // if(nodeToCheck!=node && nodeToCheck!=NULL && nodeToCheck->type==NODE_TYPE_FUNCTION) // { // char errorStr[1024];//todo: minimize length // sprintf( // errorStr, // "Main function is not the last one (%s detected line %d col %d) (compiler %s,%d)", // nodeToCheck->info->name, // nodeToCheck->debug->line, // nodeToCheck->debug->linePsn, // __FILE__, // __LINE__ // ); // onError(errorStr, __FILE__, __LINE__, node); // } // } // } } /** * Checks if the main function is the last one, without parameters, and with a void type */ void testMainPresence() { if(mainNode==NULL) { char errorStr[1024];//todo: minimize length errorStr, "Missing main function (compiler %s,%d)", __FILE__, __LINE__ ); onError(errorStr, __FILE__, __LINE__, NULL); } } /** * Fill the symbols table with the declarations * @param node AST node from witch we want to start type check */ void fillSymbolsTable(AstNode *node) { if(!isSymbolsTableAvailable()) { onError("Table of Symbols must not be NULL", __FILE__, __LINE__, node); //Failure of the compiler behavior, independent of the parsed code } if(node!=NULL) { if(node->info==NULL) { // Stop on error char errorStr[1024];//todo: minimize length sprintf(errorStr, "Missing Node Info for %20s, compiler can't perform the job (compiler %s,%d)", typeToString(node->type), __FILE__, __LINE__); onError(errorStr, __FILE__, __LINE__, node); //Failure of the compiler behavior, independent of the parsed code } node->info->scopeDepth=scopeHelperGetCurrentDepth(); node->info->scopeId=scopeHelperGetCurrentScope(); switch(node->type) { case NODE_TYPE_PARAM_DECL: if(node->subtype!=LEXICAL_VAR && node->info->type==AST_INSTACK_VAR_TYPE) { char errorStr[1024];//todo: minimize length errorStr, "%s passed by value, but %s must be passed by address, line %3d col %3d (compiler %s,%3d)", node->info->name, typeToString(AST_INSTACK_VAR_TYPE), node->debug->line, node->debug->linePsn, __FILE__, __LINE__ ); onError(errorStr, __FILE__, __LINE__, node); } addDeclaration(node); break; case NODE_TYPE_VAR_DECL: addDeclaration(node); break; case NODE_TYPE_FUNCTION: checkMainFunction(node); addDeclaration(node); enterFunctionScope(node); break; case LEXICAL_RETURN_STMT: node->info->type = ((AstNode*)scopeHelperGetCurrentFunction())->info->type; addReturnStatement(node); break; } fillSymbolsTable(node->left); fillSymbolsTable(node->right); switch(node->type) { case NODE_TYPE_FUNCTION: exitScope(); break; } } } /** * Returns true (1 in C) if the given node has the * main signature (program enter point) */ int isMainSignature(AstNode *node) { return node->left==NULL //no parameters && node->info->type == AST_VOID_VAR_TYPE //return void && node->info->scopeDepth == (INITIAL_INT+1); //program scope } /** * Checks into the table of symbols after a matching type for the given node (node) * @param node AST node from witch we want to start type check */ void checkTreeTypes(AstNode *node) { if(!isSymbolsTableAvailable()) { onError("Table of Symbols must not be NULL", __FILE__, __LINE__, node); //Failure of the compiler behavior, independent of the parsed code } if(node!=NULL) { if(node->info==NULL) { // Stop on error char errorStr[1024];//todo: minimize length sprintf(errorStr, "Missing Node Info for %20s, compiler can't perform the job (compiler %s,%d)", typeToString(node->type), __FILE__, __LINE__); onError(errorStr, __FILE__, __LINE__, node); //Failure of the compiler behavior, independent of the parsed code } #if(VERBOSE_LEVEL<=DEB_AST) if(node->type!=NODE_TYPE_VAR_DECL && node->type!=NODE_TYPE_FUNCTION) ";\n;\tCheck type for %20s %30s, line %3d col %3d (compiler %s,%3d)\n", typeToString(node->type), node->info->name, node->debug->line, node->debug->linePsn, __FILE__, __LINE__ ); #endif switch(node->type) { case NODE_TYPE_ID: node->info->computedType = getTypeWrapper(node); break; case NODE_TYPE_PARAM_DECL: //printf("\n;Check param type (%s, %d)\n", __FILE__, __LINE__); if(node->subtype!=LEXICAL_VAR && node->info->type==AST_INSTACK_VAR_TYPE) { char errorStr[1024];//todo: minimize length errorStr, "%s passed by value, but %s must be passed by address, line %3d col %3d (compiler %s,%3d)", node->info->name, typeToString(AST_INSTACK_VAR_TYPE), node->debug->line, node->debug->linePsn, __FILE__, __LINE__ ); onError(errorStr, __FILE__, __LINE__, node); } //addDeclaration(node); break; case NODE_TYPE_DECLARATION: //addDeclaration(node); break; case NODE_TYPE_REXP: checkOperationTypes(node); break; case NODE_TYPE_FUNCTION_CALL: getTypeWrapper(node); break; // case NODE_TYPE_PARAM_LIST: // getTypeWrapper(node); // break; case LEXICAL_WRITE_OPS: case LEXICAL_READ_OPS: checkType(getTypeWrapper(node->right), AST_INTEGER_VAR_TYPE, node, __FILE__, __LINE__); break; case LEXICAL_PUT_OPS: checkType(getTypeWrapper(node->left), AST_INSTACK_VAR_TYPE, node, __FILE__, __LINE__); checkType(getTypeWrapper(node->right), AST_INTEGER_VAR_TYPE, node, __FILE__, __LINE__); break; case NODE_TYPE_STATEMENT: { int rightType=INITIAL_INT; if(node->subtype==LEXICAL_AFFECTATION) { rightType=getTypeWrapper(node->right); switch(rightType) { case AST_INTEGER_ARRAY_VAR_TYPE: rightType=AST_INTEGER_VAR_TYPE; break; case AST_BOOLEAN_ARRAY_VAR_TYPE: rightType=AST_BOOLEAN_VAR_TYPE; break; } } if(node->info->type == NODE_TYPE_CHECK) { //check right and left types int leftType = getTypeWrapper(node->left); if(rightType==INITIAL_INT) { rightType=getTypeWrapper(node->right); } checkType(rightType, leftType, node, __FILE__, __LINE__); } } break; case NODE_TYPE_FUNCTION: #if(VERBOSE_LEVEL<=DEB_AST) node->info->name, node, typeToString(node->info->type), (mainNode!=NULL)?"yes":"no", __FILE__, __LINE__ ); #endif enterFunctionScope(node); break; case NODE_TYPE_FUNCTIONS: break; default: switch(node->subtype) { case LEXICAL_IF_STMT: case AST_IF_ELSE_STMT: case LEXICAL_WHILE_STMT: checkType(getTypeWrapper(node->left), AST_BOOLEAN_VAR_TYPE, node, __FILE__, __LINE__); //scopeHelperEnterScope(); break; case LEXICAL_FOR_STMT: if(node->left!=NULL) { checkType(getTypeWrapper(node->left), AST_BOOLEAN_VAR_TYPE, node, __FILE__, __LINE__); } //scopeHelperEnterScope(); break; } } checkTreeTypes(node->left); checkTreeTypes(node->right); switch(node->type) { case NODE_TYPE_FUNCTION: checkReturnStatement(node); //case NODE_TYPE_LEXICAL_FOR_STMT: exitScope(); break; } } } /** * Sets debug informations into an AST node. This allows keeping the location * of the current item into the parsed code * In this case, don't care about freeing it, it's delegate to the node finalization */ void setDebug(AstNode *node, debugYacc yaccPsn) { DebugInfo *debug=createDebug(); debug->line=yaccPsn==NULL?ERROR_INT:yaccPsn->first_line; debug->linePsn=yaccPsn==NULL?ERROR_INT:yaccPsn->first_column; node->debug=debug; } /** * Sets given node as parent for the children of the given node */ void setParent(AstNode *node) { if(node!=NULL) { if(node->right!=NULL) { node->right->parent=node; } if(node->left!=NULL) { node->left->parent=node; } } } /** * Cleans memory allocated for the AST */ void finalizeTree(AstNode *node) { if (node != NULL) { if (node->info != NULL) { } if (node->debug != NULL) { } //Must not free parent! if (node->left != NULL) finalizeTree(node->left); if (node->right != NULL) finalizeTree(node->right); } } /** * Sets a unique name to an unnamed node */ void setIncrementedName(AstNodeInfo *info) { char incremName[32]; char *str = incremName; nameIncrementor++; //printf("\n;\t--- %s",str); } /* * ********************************************************** * Implementation of the header exposed items * See ast.h for these functions comments * ********************************************************** */ AstNodeInfo* createASTNodeInfo(char *name, int type, int value) { if(!pNodeInfo) { if(VERBOSE_LEVEL<=DEB_E) { printMsg(DEB_E,"Allocation Error(AST node info)", __FILE__, __LINE__); } //Failure of the compiler behavior, independent of the parsed code } //put a unique generated name if null, to allow checking into sym table { setIncrementedName(pNodeInfo); } else { pNodeInfo->name=name; } // //Must keep a copy // pNodeInfo->varName=calloc(strlen(pNodeInfo->name)+1, sizeof(char)); // strcpy(pNodeInfo->varName, pNodeInfo->name); pNodeInfo->type = type; pNodeInfo->computedType=AST_TODO; pNodeInfo->value=value; pNodeInfo->declarationNode=NULL; pNodeInfo->memoryLocation=INITIAL_INT; pNodeInfo->scopeId = scopeHelperGetCurrentScope(); pNodeInfo->scopeDepth = scopeHelperGetCurrentDepth();//INITIAL_INT; pNodeInfo->returnStatement=NULL; if(VERBOSE_LEVEL<=DEB_AST) { ";\n\tCreation of Node Info %20s %40s On %s, Line %d\n", typeToString(pNodeInfo->type), pNodeInfo->name, __FILE__, __LINE__ ); } return pNodeInfo; } void checkAST() { #if(VERBOSE_LEVEL<=DEB_EXEC) printMsg(DEB_EXEC,"1st AST walk: filling symbols table...", __FILE__, __LINE__); #endif scopeHelperEnterScope(); fillSymbolsTable(rootNode); resetScopeHelper(); scopeHelperEnterScope(); #if(VERBOSE_LEVEL<=DEB_EXEC) printMsg(DEB_EXEC,"2nd AST walk: checking types and constraints...", __FILE__, __LINE__); #endif checkTreeTypes(rootNode); //testMainPresence(); } DebugInfo* createDebug() { if(!debug) { if(VERBOSE_LEVEL<=DEB_E) { printMsg(DEB_E,"Allocation Error(Debug info)", __FILE__, __LINE__); } //Failure of the compiler behavior, independent of the parsed code } // todo : get name from parsed file (all ways are OS dependent) // if(yyin!=NULL) // { // debug->file=yyin->f_name; // } // else // { debug->file="parsed code"; // } debug->line=0; debug->linePsn=0; return debug; } void setNodeType(AstNode *node, int type) { node->type = type; } void setNodeSubType(AstNode *node, int subtype) { node->subtype = subtype; } void setComputedType(AstNode *node, int varType) { node->info->type = varType; node->info->computedType=varType; } AstNode* createASTNode(debugYacc yaccPsn, int type, AstNodeInfo *info, AstNode *left, AstNode *right) { if(!pNode) { if(VERBOSE_LEVEL<=DEB_E) { printMsg(DEB_E,"Allocation Error(AST node)", __FILE__, __LINE__); } //Failure of the compiler behavior, independent of the parsed code } pNode->type=type; pNode->info=info; pNode->right=right; pNode->left=left; pNode->subtype=NODE_TYPE_NOTHING; setParent(pNode); setDebug(pNode, yaccPsn); if(VERBOSE_LEVEL<=DEB_O) { typeToString(pNode->type), typeToString(pNode->info->type), pNode->info->name,//(info!=NULL)?info->name:"?", __FILE__, __LINE__ ); } return pNode; } int isBefore(AstNode *node1, AstNode *node2) { if(node1==NULL)return -2; if(node2==NULL)return -3; if(node1==node2) return AST_CMP_EQUALS; if(node1->debug->line < node2->debug->line)return AST_CMP_BEFORE; if((node1->debug->line == node2->debug->line) && (node1->debug->linePsn < node2->debug->linePsn))return AST_CMP_BEFORE; return AST_CMP_AFTER; } AstNode *getMain() { return mainNode; } void finalizeAST() { finalizeTree(rootNode); } char* typeToString(int type) { char *str = NULL; switch(type) { case NODE_TYPE_TODO: str = "NODE_TYPE_TODO"; break; case NODE_TYPE_CHECK: str = "NODE_TYPE_CHECK"; break; case NODE_TYPE_NOTHING: str = "type not set"; break; case NODE_TYPE_CONTAINER: str = "Structural node"; break; case NODE_TYPE_FUNCTION_CALL: str = "function call"; break; case AST_VOID_VAR_TYPE: str = "void"; break; case AST_BOOLEAN_VAR_TYPE: str = "boolean"; break; case AST_INTEGER_VAR_TYPE: str = "integer"; break; case AST_INSTACK_VAR_TYPE: str = "intstack"; break; case AST_INTEGER_ARRAY_VAR_TYPE: str = "array of integers"; break; case AST_BOOLEAN_ARRAY_VAR_TYPE: str = "array of booleans"; break; case NODE_TYPE_FUNCTIONS: str = "Functions"; break; case NODE_TYPE_FUNCTION: str = "Function"; break; case NODE_TYPE_DECLARATIONS: str = "Type declarations"; break; case NODE_TYPE_DECLARATION: str = "Type declaration"; break; case NODE_TYPE_FUNCTION_BODY: str = "function body"; break; case NODE_TYPE_STATEMENT: str = "Statement"; break; case NODE_TYPE_REXP: str = "Right expression"; break; case NODE_TYPE_ID: str = "Id"; break; case NODE_TYPE_VAR_DECL: str = "Variable declaration"; break; case NODE_TYPE_PARAM_LIST: str = "Parameters list"; break; case NODE_TYPE_PARAM: str = "Parameter"; break; case NODE_DECL_PADR: str = "By address parameter"; break; case NODE_DECL_PVAL: str = "By value parameter"; break; case LEXICAL_AFFECTATION: str = "="; break; case LEXICAL_PLUS: str = "+"; break; case LEXICAL_MINUS: str = "-"; break; case LEXICAL_MULT: str = "*"; break; case LEXICAL_AND: str = "&&"; break; case LEXICAL_OR: str = "||"; break; case LEXICAL_LESS: str = "<"; break; case LEXICAL_LESS_EQUALS: str = "<="; break; case LEXICAL_DIV: str = "div"; break; case LEXICAL_MOD: str = "mod"; break; case LEXICAL_EQUALS: str = "=="; break; case LEXICAL_NOT: str = "!"; break; // yytokentype enum case LEXICAL_TRUE_VAL: str = "true"; break; case LEXICAL_FALSE_VAL: str = "false"; break; case NUMBER: str = "number"; break; case LEXICAL_ISEMPTY_OPS: str = "ISEMPTY"; break; case LEXICAL_GET_OPS: str = "GET"; break; case LEXICAL_WRITE_OPS: str = "WRITE"; break; case LEXICAL_READ_OPS: str = "READ"; break; case LEXICAL_RETURN_STMT: str="return"; break; case NODE_TYPE_PARAM_DECL: str="NODE_TYPE_PARAM_DECL"; break; case ID : str="ID"; break; case LEXICAL_VAR : str="LEXICAL_VAR"; break; //Internal business case AST_TODO: str="Not yet defined"; break; default: str = "undefined"; #if(VERBOSE_LEVEL<=DEB_W) char str[1024];//todo: minimize length printMsg(DEB_W, str, __FILE__, __LINE__); #endif break; } return str; }
Autres extraits de codes en c
- DisquetteDispo Vérifier la disponibilité du lecteur de disquette
- Suite de Fibonacci Exemple d'itération en C
- Suite de Fibonacci Exemple de récursion en C
- astDataRepresentation.h Représentation de données de l'arbre syntaxique abstrait Compilateur LSD010
- ast.h Arbre syntaxique abstrait Compilateur LSD010
- ast.c Arbre syntaxique abstrait Compilateur LSD010
- symbolsTableDataRepresentation.h Représentation de données de la table des symboles Compilateur LSD010
- symbolsTable.h Fonctions de gestion de la table des symboles Compilateur LSD010
- symbolsTable.c Fonctions de gestion de la table des symboles Compilateur LSD010
- hashCode.h Fonctions de hachage Compilateur LSD010
- hashCode.c Fonctions de hachage Compilateur LSD010
- scopeStack.h Fonctions de gestion d'une pile de portées Compilateur LSD010
- scopeStack.c Fonctions de gestion d'une pile de portées Compilateur LSD010
- scopeHelper.h Fonctions de gestion de la portée courante Compilateur LSD010
- console.h Fonctions d'affichage Compilateur LSD010
- console.c Fonctions d'affichage Compilateur LSD010
- graphVizHelper.h Génération d'une image d'un arbre syntaxique abstrait.
Classe d'intégration de l'outil GraphViz. Compilateur LSD010 - graphVizHelper.c Génération d'une image d'un arbre syntaxique abstrait.
Classe d'intégration de l'outil GraphViz. Compilateur LSD010 - common.h Définition des constantes et variables communes Compilateur LSD010
- pcode.c Génération de p-code Compilateur LSD010
- pcode.h Génération de p-code Compilateur LSD010
- Tous les extraits
Version en cache
21/11/2024 11:47:44 Cette version de la page est en cache (à la date du 21/11/2024 11:47:44) 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/ast.c.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.