ast.c
Description du code
ast.c est un fichier du projet Compilateur LSD010.Ce fichier est situé dans /var/www/bin/sniplets/lsd010/.
Projet Compilateur LSD010 :
Compilateur LSD010 développé dans le cadre du cours de syntaxe et sémantiqueref 1
Code 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; }
Structure et Fichiers du projet
Afficher/masquer...Icône | Nom | Taille | Modification |
Pas de sous-répertoires. | |||
Icône | Nom | Taille | Modification |
| _ | Répertoire parent | 0 octets | 1732316351 22/11/2024 23:59:11 |
Warnung
Ce code présente une manière possible d'implémenter un compilateur, et certains choix peuvent être discutés.Cependant, il peut donner des pistes pour démarrer, ou approcher certains concepts, et je tenterais par la suite de mettre à jour le code.
Utilisation de l'explorateur de code
- Navigation :
- Un clic sur une icône de répertoire ouvre ce répertoire pour en afficher les fichiers.
- Lorsque le répertoire en cours ne contient pas de sous-répertoires il est possible de remonter vers le répertoire parent.
- La structure de répertoires en treetable (tableau en forme d'arborescence) n'est plus possibledans cette version.
- Un clic sur une icône de fichier ouvre ce fichier pour en afficher le code avec la coloration syntaxique adaptée en fonction du langage principal utilisé dans le fichier.
- Affichage :
- Il est possible de trier les répertoires ou les fichiers selon certains critères (nom, taille, date).
- Actions :
- Les actions possible sur les fichiers dépendent de vos droits d'utilisateur sur le site. Veuillez activer le mode utilisateur pour activer les actions.
Deutsche Übersetzung
Sie haben gebeten, diese Seite auf Deutsch zu besuchen. Momentan ist nur die Oberfläche übersetzt, aber noch nicht der gesamte Inhalt.Wenn Sie mir bei Übersetzungen helfen wollen, ist Ihr Beitrag willkommen. Alles, was Sie tun müssen, ist, sich auf der Website zu registrieren und mir eine Nachricht zu schicken, in der Sie gebeten werden, Sie der Gruppe der Übersetzer hinzuzufügen, die Ihnen die Möglichkeit gibt, die gewünschten Seiten zu übersetzen. Ein Link am Ende jeder übersetzten Seite zeigt an, dass Sie der Übersetzer sind und einen Link zu Ihrem Profil haben.
Vielen Dank im Voraus.
Dokument erstellt 07/03/2010, zuletzt geändert 28/10/2018
Quelle des gedruckten Dokuments:https://www.gaudry.be/de/langages-lsd10-source-rf-project/source/ast.c.html
Die Infobro ist eine persönliche Seite, deren Inhalt in meiner alleinigen Verantwortung liegt. Der Text ist unter der CreativeCommons-Lizenz (BY-NC-SA) verfügbar. Weitere Informationen auf die Nutzungsbedingungen und dem Autor.
- ↑a,b LSD010 : Langage Simple et Didactique Il existe une un certain nombre d'interprétations de l'acronyme LSD (Langage Symbolique Didactique, Langage Sans Difficulté, Langage Simple et Didactique). LSD010 est la version 2010 de la suite LSD80, LSD_02, LSD03, LSD04, LSD05, LSD06, LSD07, LSD08, et LSD09.
Referenzen
- IHDCB332 - Théorie des langages : Syntaxe et sémantique : PY Schobbens,
Syntaxe et sémantique
(January 2010)
Diese Verweise und Links verweisen auf Dokumente, die während des Schreibens dieser Seite konsultiert wurden, oder die zusätzliche Informationen liefern können, aber die Autoren dieser Quellen können nicht für den Inhalt dieser Seite verantwortlich gemacht werden.
Der Autor Diese Website ist allein dafür verantwortlich, wie die verschiedenen Konzepte und Freiheiten, die mit den Nachschlagewerken gemacht werden, hier dargestellt werden. Denken Sie daran, dass Sie mehrere Quellinformationen austauschen müssen, um das Risiko von Fehlern zu reduzieren.