?? pattern.c
字號:
tempNode1->singleFieldsBefore = runningSingleFields; tempNode1->multiFieldsBefore = runningMultiFields; tempNode1->withinMultifieldSlot = TRUE; if ((tempNode1->type == SF_VARIABLE) || (tempNode1->type == SF_WILDCARD)) { tempNode1->singleFieldsAfter = (unsigned short) (totalSingleFields - (runningSingleFields + 1)); tempNode1->multiFieldsAfter = (unsigned short) (totalMultiFields - runningMultiFields); } else { tempNode1->singleFieldsAfter = (unsigned short) (totalSingleFields - runningSingleFields); tempNode1->multiFieldsAfter = (unsigned short) (totalMultiFields - (runningMultiFields + 1)); } /*=====================================================*/ /* Assign the values to each of the and (&) and or (|) */ /* connected constraints within the constraint. */ /*=====================================================*/ for (tempNode2 = tempNode1->bottom; tempNode2 != NULL; tempNode2 = tempNode2->bottom) { for (tempNode3 = tempNode2; tempNode3 != NULL; tempNode3 = tempNode3->right) { tempNode3->singleFieldsBefore = tempNode1->singleFieldsBefore; tempNode3->singleFieldsAfter = tempNode1->singleFieldsAfter; tempNode3->multiFieldsBefore = tempNode1->multiFieldsBefore; tempNode3->multiFieldsAfter = tempNode1->multiFieldsAfter; tempNode3->withinMultifieldSlot = TRUE; } } /*=======================================*/ /* Calculate the running total of single */ /* and multifield constraints. */ /*=======================================*/ if ((tempNode1->type == SF_VARIABLE) || (tempNode1->type == SF_WILDCARD)) { runningSingleFields++; } else { runningMultiFields++; } } }/*******************************************************************//* ConjuctiveRestrictionParse: Parses a single constraint field in *//* a pattern that is not a single field wildcard, multifield *//* wildcard, or multifield variable. The field may consist of a *//* number of subfields tied together using the & connective *//* constraint and/or the | connective constraint. *//* *//* <connected-constraint> *//* ::= <single-constraint> | *//* <single-constraint> & <connected-constraint> | *//* <single-constraint> | <connected-constraint> *//*******************************************************************/static struct lhsParseNode *ConjuctiveRestrictionParse( void *theEnv, char *readSource, struct token *theToken, int *error) { struct lhsParseNode *bindNode; struct lhsParseNode *theNode, *nextOr, *nextAnd; int connectorType; /*=====================================*/ /* Get the first node and determine if */ /* it is a binding variable. */ /*=====================================*/ theNode = LiteralRestrictionParse(theEnv,readSource,theToken,error); if (*error == TRUE) { return(NULL); } GetToken(theEnv,readSource,theToken); if (((theNode->type == SF_VARIABLE) || (theNode->type == MF_VARIABLE)) && (theNode->negated == FALSE) && (theToken->type != OR_CONSTRAINT)) { theNode->bindingVariable = TRUE; bindNode = theNode; nextOr = NULL; nextAnd = NULL; } else { bindNode = GetLHSParseNode(theEnv); if (theNode->type == MF_VARIABLE) bindNode->type = MF_WILDCARD; else bindNode->type = SF_WILDCARD; bindNode->negated = FALSE; bindNode->bottom = theNode; nextOr = theNode; nextAnd = theNode; } /*===================================*/ /* Process the connected constraints */ /* within the constraint */ /*===================================*/ while ((theToken->type == OR_CONSTRAINT) || (theToken->type == AND_CONSTRAINT)) { /*==========================*/ /* Get the next constraint. */ /*==========================*/ connectorType = theToken->type; GetToken(theEnv,readSource,theToken); theNode = LiteralRestrictionParse(theEnv,readSource,theToken,error); if (*error == TRUE) { ReturnLHSParseNodes(theEnv,bindNode); return(NULL); } /*=======================================*/ /* Attach the new constraint to the list */ /* of constraints for this field. */ /*=======================================*/ if (connectorType == OR_CONSTRAINT) { if (nextOr == NULL) { bindNode->bottom = theNode; } else { nextOr->bottom = theNode; } nextOr = theNode; nextAnd = theNode; } else if (connectorType == AND_CONSTRAINT) { if (nextAnd == NULL) { bindNode->bottom = theNode; nextOr = theNode; } else { nextAnd->right = theNode; } nextAnd = theNode; } else { SystemError(theEnv,"RULEPSR",1); EnvExitRouter(theEnv,EXIT_FAILURE); } /*==================================================*/ /* Determine if any more restrictions are connected */ /* to the current list of restrictions. */ /*==================================================*/ GetToken(theEnv,readSource,theToken); } /*==========================================*/ /* Check for illegal mixing of single and */ /* multifield values within the constraint. */ /*==========================================*/ if (CheckForVariableMixing(theEnv,bindNode)) { *error = TRUE; ReturnLHSParseNodes(theEnv,bindNode); return(NULL); } /*========================*/ /* Return the constraint. */ /*========================*/ return(bindNode); }/*****************************************************//* CheckForVariableMixing: Checks a field constraint *//* to determine if single and multifield variables *//* are illegally mixed within it. *//*****************************************************/static int CheckForVariableMixing( void *theEnv, struct lhsParseNode *theRestriction) { struct lhsParseNode *tempRestriction; CONSTRAINT_RECORD *theConstraint; int multifield = FALSE; int singlefield = FALSE; int constant = FALSE; int singleReturnValue = FALSE; int multiReturnValue = FALSE; /*================================================*/ /* If the constraint contains a binding variable, */ /* determine whether it is a single field or */ /* multifield variable. */ /*================================================*/ if (theRestriction->type == SF_VARIABLE) singlefield = TRUE; else if (theRestriction->type == MF_VARIABLE) multifield = TRUE; /*===========================================*/ /* Loop through each of the or (|) connected */ /* constraints within the constraint. */ /*===========================================*/ for (theRestriction = theRestriction->bottom; theRestriction != NULL; theRestriction = theRestriction->bottom) { /*============================================*/ /* Loop through each of the and (&) connected */ /* constraints within the or (|) constraint. */ /*============================================*/ for (tempRestriction = theRestriction; tempRestriction != NULL; tempRestriction = tempRestriction->right) { /*=====================================================*/ /* Determine if the constraint contains a single field */ /* variable, multifield variable, constant (a single */ /* field), a return value constraint of a function */ /* returning a single field value, or a return value */ /* constraint of a function returning a multifield */ /* value. */ /*=====================================================*/ if (tempRestriction->type == SF_VARIABLE) singlefield = TRUE; else if (tempRestriction->type == MF_VARIABLE) multifield = TRUE; else if (ConstantType(tempRestriction->type)) constant = TRUE; else if (tempRestriction->type == RETURN_VALUE_CONSTRAINT) { theConstraint = FunctionCallToConstraintRecord(theEnv,tempRestriction->expression->value); if (theConstraint->anyAllowed) { /* Do nothing. */ } else if (theConstraint->multifieldsAllowed) multiReturnValue = TRUE; else singleReturnValue = TRUE; RemoveConstraint(theEnv,theConstraint); } } } /*================================================================*/ /* Using a single field value (a single field variable, constant, */ /* or function returning a single field value) together with a */ /* multifield value (a multifield variable or function returning */ /* a multifield value) is illegal. Return TRUE if this occurs. */ /*================================================================*/ if ((singlefield || constant || singleReturnValue) && (multifield || multiReturnValue)) { PrintErrorID(theEnv,"PATTERN",2,TRUE); EnvPrintRouter(theEnv,WERROR,"Single and multifield constraints cannot be mixed in a field constraint\n"); return(TRUE); } /*=======================================*/ /* Otherwise return FALSE to indicate no */ /* illegal variable mixing was detected. */ /*=======================================*/ return(FALSE); }/***********************************************************//* LiteralRestrictionParse: Parses a single constraint. *//* The constraint may be a literal constraint, a *//* predicate constraint, a return value constraint, or a *//* variable constraint. The constraints may also be *//* negated using the ~ connective constraint. *//* *//* <single-constraint> ::= <term> | ~<term> *//* *//* <term> ::= <constant> | *//* <single-field-variable> | *//* <multi-field-variable> | *//* :<function-call> | *//* =<function-call> *//***********************************************************/static struct lhsParseNode *LiteralRestrictionParse( void *theEnv, char *readSource, struct token *theToken, int *error) { struct lhsParseNode *topNode; struct expr *theExpression; /*============================================*/ /* Create a node to represent the constraint. */ /*============================================*/ topNode = GetLHSParseNode(theEnv); /*=================================================*/ /* Determine if the constraint has a '~' preceding */ /* it. If it does, then the field is negated */ /* (e.g. ~red means "not the constant red." */ /*=================================================*/ if (theToken->type == NOT_CONSTRAINT) { GetToken(theEnv,readSource,theToken); topNode->negated = TRUE; } else { topNode->negated = FALSE; } /*===========================================*/ /* Determine if the constraint is one of the */ /* recognized types. These are ?variables, */ /* symbols, strings, numbers, :(expression), */ /* and =(expression). */ /*===========================================*/ topNode->type = theToken->type; /*============================================*/ /* Any symbol is valid, but an = signifies a */ /* return value constraint and an : signifies */ /* a predicate constraint. */ /*============================================*/ if (theToken->type == SYMBOL) { /*==============================*/ /* If the symbol is an =, parse */ /* a return value constraint. */ /*==============================*/ if (strcmp(ValueToString(theToken->value),"=") == 0) { theExpression = Function0Parse(theEnv,readSource); if (theExpression == NULL) { *error = TRUE; ReturnLHSParseNodes(theEnv,topNode); return(NULL); } topNode->type = RETURN_VALUE_CONSTRAINT; topNode->expression = ExpressionToLHSParseNodes(theEnv,theExpression); ReturnExpression(theEnv,theExpression); } /*=============================*/ /* If the symbol is a :, parse */ /* a predicate constraint. */ /*=============================*/ else if (strcmp(ValueToString(theToken->value),":") == 0) { theExpression = Function0Parse(theEnv,readSource); if (theExpression == NULL) { *error = TRUE; ReturnLHSParseNodes(theEnv,topNode); return(NULL); } topNode->type = PREDICATE_CONSTRAINT; topNode->expression = ExpressionToLHSParseNodes(theEnv,theExpression); ReturnExpression(theEnv,theExpression); } /*==============================================*/ /* Otherwise, treat the constraint as a symbol. */ /*==============================================*/ else { topNode->value = theToken->value; } } /*=====================================================*/ /* Single and multifield variables and float, integer, */ /* string, and instance name constants are also valid. */ /*=====================================================*/ else if ((theToken->type == SF_VARIABLE) || (theToken->type == MF_VARIABLE) || (theToken->type == FLOAT) || (theToken->type == INTEGER) || (theToken->type == STRING) || (theToken->type == INSTANCE_NAME)) { topNode->value = theToken->value; } /*===========================*/ /* Anything else is invalid. */ /*===========================*/ else { SyntaxErrorMessage(theEnv,"defrule"); *error = TRUE; ReturnLHSParseNodes(theEnv,topNode); return(NULL); } /*===============================*/ /* Return the parsed constraint. */ /*===============================*/ return(topNode); }#endif /* (! RUN_TIME) && (! BLOAD_ONLY) */#endif /* DEFRULE_CONSTRUCT */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -