📄 modulpsr.c
字号:
/*==========================================*/ /* Parse import/export specifications until */ /* a right parenthesis is encountered. */ /*==========================================*/ while (theToken->type != RPAREN) { /*========================================*/ /* Look for the opening left parenthesis. */ /*========================================*/ if (theToken->type != LPAREN) { SyntaxErrorMessage("defmodule"); return(CLIPS_TRUE); } /*====================================*/ /* Look for the import/export keyword */ /* and call the appropriate functions */ /* for parsing the specification. */ /*====================================*/ GetToken(readSource,theToken); if (theToken->type != SYMBOL) { SyntaxErrorMessage("defmodule"); return(CLIPS_TRUE); } if (strcmp(ValueToString(theToken->value),"import") == 0) { error = ParseImportSpec(readSource,theToken,theDefmodule); } else if (strcmp(ValueToString(theToken->value),"export") == 0) { error = ParseExportSpec(readSource,theToken,theDefmodule,NULL); } else { SyntaxErrorMessage("defmodule"); return(CLIPS_TRUE); } if (error) return(CLIPS_TRUE); /*============================================*/ /* Begin parsing the next port specification. */ /*============================================*/ PPCRAndIndent(); GetToken(readSource,theToken); if (theToken->type == RPAREN) { PPBackup(); PPBackup(); SavePPBuffer(")"); } } /*===================================*/ /* Return FALSE to indicate no error */ /* occurred while parsing the */ /* import/export specifications. */ /*===================================*/ return(CLIPS_FALSE); } /**********************************************************//* ParseImportSpec: Parses import specifications found in *//* a defmodule construct. *//* *//* <import-spec> ::= (import <module-name> <port-item>) *//* *//* <port-item> ::= ?ALL | *//* ?NONE | *//* <construct-name> ?ALL | *//* <construct-name> ?NONE | *//* <construct-name> <names>* *//**********************************************************/static int ParseImportSpec(readSource,theToken,newModule) char *readSource; struct token *theToken; struct defmodule *newModule; { struct defmodule *theModule; struct portItem *thePort, *oldImportSpec; int found, count; /*===========================*/ /* Look for the module name. */ /*===========================*/ SavePPBuffer(" "); GetToken(readSource,theToken); if (theToken->type != SYMBOL) { SyntaxErrorMessage("defmodule import specification"); return(CLIPS_TRUE); } /*=====================================*/ /* Verify the existence of the module. */ /*=====================================*/ if ((theModule = (struct defmodule *) FindDefmodule(ValueToString(theToken->value))) == NULL) { CantFindItemErrorMessage("defmodule",ValueToString(theToken->value)); return(CLIPS_TRUE); } /*========================================*/ /* If the specified module doesn't export */ /* any constructs, then the import */ /* specification is meaningless. */ /*========================================*/ if (theModule->exportList == NULL) { NotExportedErrorMessage(GetDefmoduleName(theModule),NULL,NULL); return(CLIPS_TRUE); } /*==============================================*/ /* Parse the remaining portion of the import */ /* specification and return if an error occurs. */ /*==============================================*/ oldImportSpec = newModule->importList; if (ParseExportSpec(readSource,theToken,newModule,theModule)) return(CLIPS_TRUE); /*========================================================*/ /* If the ?NONE keyword was used with the import spec, */ /* then no constructs were actually imported and the */ /* import spec does not need to be checked for conflicts. */ /*========================================================*/ if (newModule->importList == oldImportSpec) return(CLIPS_FALSE); /*======================================================*/ /* Check to see if the construct being imported can be */ /* by the specified module. This check exported doesn't */ /* guarantee that a specific named construct actually */ /* exists. It just checks that it could be exported if */ /* it does exists. */ /*======================================================*/ if (newModule->importList->constructType != NULL) { /*=============================*/ /* Look for the construct in */ /* the module that exports it. */ /*=============================*/ found = CLIPS_FALSE; for (thePort = theModule->exportList; (thePort != NULL) && (! found); thePort = thePort->next) { if (thePort->constructType == NULL) found = CLIPS_TRUE; else if (thePort->constructType == newModule->importList->constructType) { if (newModule->importList->constructName == NULL) found = CLIPS_TRUE; else if (thePort->constructName == NULL) found = CLIPS_TRUE; else if (thePort->constructName == newModule->importList->constructName) { found = CLIPS_TRUE; } } } /*=======================================*/ /* If it's not exported by the specified */ /* module, print an error message. */ /*=======================================*/ if (! found) { if (newModule->importList->constructName == NULL) { NotExportedErrorMessage(GetDefmoduleName(theModule), ValueToString(newModule->importList->constructType), NULL); } else { NotExportedErrorMessage(GetDefmoduleName(theModule), ValueToString(newModule->importList->constructType), ValueToString(newModule->importList->constructName)); } return(CLIPS_TRUE); } } /*======================================================*/ /* Verify that specific named constructs actually exist */ /* and can be seen from the module importing them. */ /*======================================================*/ SaveCurrentModule(); SetCurrentModule((VOID *) newModule); for (thePort = newModule->importList; thePort != NULL; thePort = thePort->next) { if ((thePort->constructType == NULL) || (thePort->constructName == NULL)) { continue; } theModule = (struct defmodule *) FindDefmodule(ValueToString(thePort->moduleName)); SetCurrentModule(theModule); if (FindImportedConstruct(ValueToString(thePort->constructType),NULL, ValueToString(thePort->constructName),&count, CLIPS_TRUE,CLIPS_FALSE) == NULL) { NotExportedErrorMessage(GetDefmoduleName(theModule), ValueToString(thePort->constructType), ValueToString(thePort->constructName)); RestoreCurrentModule(); return(CLIPS_TRUE); } } RestoreCurrentModule(); /*===============================================*/ /* The import list has been successfully parsed. */ /*===============================================*/ return(CLIPS_FALSE); } /**********************************************************//* ParseExportSpec: Parses export specifications found in *//* a defmodule construct. This includes parsing the *//* remaining specification found in an import *//* specification after the module name. *//**********************************************************/static int ParseExportSpec(readSource,theToken,newModule,importModule) char *readSource; struct token *theToken; struct defmodule *newModule; struct defmodule *importModule; { struct portItem *newPort; SYMBOL_HN *theConstruct, *moduleName; struct portConstructItem *thePortConstruct; char *errorMessage; /*===========================================*/ /* Set up some variables for error messages. */ /*===========================================*/ if (importModule != NULL) { errorMessage = "defmodule import specification"; moduleName = importModule->name; } else { errorMessage = "defmodule export specification"; moduleName = NULL; } /*=============================================*/ /* Handle the special variables ?ALL and ?NONE */ /* in the import/export specification. */ /*=============================================*/ SavePPBuffer(" "); GetToken(readSource,theToken); if (theToken->type == SF_VARIABLE) { /*==============================*/ /* Check to see if the variable */ /* is either ?ALL or ?NONE. */ /*==============================*/ if (strcmp(ValueToString(theToken->value),"ALL") == 0) { newPort = (struct portItem *) get_struct(portItem); newPort->moduleName = moduleName; newPort->constructType = NULL; newPort->constructName = NULL; newPort->next = NULL; } else if (strcmp(ValueToString(theToken->value),"NONE") == 0) { newPort = NULL; } else { SyntaxErrorMessage(errorMessage); return(CLIPS_TRUE); } /*=======================================================*/ /* The export/import specification must end with a right */ /* parenthesis after ?ALL or ?NONE at this point. */ /*=======================================================*/ GetToken(readSource,theToken); if (theToken->type != RPAREN) { if (newPort != NULL) rtn_struct(portItem,newPort); PPBackup(); SavePPBuffer(" "); SavePPBuffer(theToken->printForm); SyntaxErrorMessage(errorMessage); return(CLIPS_TRUE); } /*=====================================*/ /* Add the new specification to either */ /* the import or export list. */ /*=====================================*/ if (newPort != NULL) { if (importModule != NULL) { newPort->next = newModule->importList; newModule->importList = newPort; } else { newPort->next = newModule->exportList; newModule->exportList = newPort; } } /*============================================*/ /* Return FALSE to indicate the import/export */ /* specification was successfully parsed. */ /*============================================*/ return(CLIPS_FALSE); } /*========================================================*/ /* If the ?ALL and ?NONE keywords were not used, then the */ /* token must be the name of an importable construct. */ /*========================================================*/ if (theToken->type != SYMBOL) { SyntaxErrorMessage(errorMessage); return(CLIPS_TRUE); } theConstruct = (SYMBOL_HN *) theToken->value; if ((thePortConstruct = ValidPortConstructItem(ValueToString(theConstruct))) == NULL) { SyntaxErrorMessage(errorMessage); return(CLIPS_TRUE); } /*=============================================================*/ /* If the next token is the special variable ?ALL, then all */ /* constructs of the specified type are imported/exported. If */ /* the next token is the special variable ?NONE, then no */ /* constructs of the specified type will be imported/exported. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -