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
English translation
You have asked to visit this site in English. For now, only the interface is translated, but not all the content yet.If you want to help me in translations, your contribution is welcome. All you need to do is register on the site, and send me a message asking me to add you to the group of translators, which will give you the opportunity to translate the pages you want. A link at the bottom of each translated page indicates that you are the translator, and has a link to your profile.
Thank you in advance.
Document created the 05/10/2009, last modified the 28/10/2018
Source of the printed document:https://www.gaudry.be/en/sniplet-rf-lsd010/project/source/ast.c.html
The infobrol is a personal site whose content is my sole responsibility. The text is available under CreativeCommons license (BY-NC-SA). More info on the terms of use and the author.