📄 rulelhs.c
字号:
(connectorValue == NOT_CE))
{
theNode->type = connectorValue;
theNode->right = theGroup;
}
/*=================================================================*/
/* Wrap two not CEs around the patterns contained in an exists CE. */
/*=================================================================*/
else if (connectorValue == EXISTS_CE)
{
theNode->type = NOT_CE;
theNode->right = GetLHSParseNode(theEnv);
theNode->right->type = NOT_CE;
theNode->right->logical = logical;
if (theGroup->bottom != NULL)
{
theNode->right->right = GetLHSParseNode(theEnv);
theNode->right->right->type = AND_CE;
theNode->right->right->logical = logical;
theNode->right->right->right = theGroup;
}
else
{ theNode->right->right = theGroup; }
}
/*==================================================*/
/* For a forall CE, wrap a not CE around all of the */
/* CEs and a not CE around the 2nd through nth CEs. */
/*==================================================*/
else if (connectorValue == FORALL_CE)
{
theNode->type = NOT_CE;
tempNode = theGroup->bottom;
theGroup->bottom = NULL;
theNode->right = GetLHSParseNode(theEnv);
theNode->right->type = AND_CE;
theNode->right->logical = logical;
theNode->right->right = theGroup;
theGroup = tempNode;
theNode->right->right->bottom = GetLHSParseNode(theEnv);
theNode->right->right->bottom->type = NOT_CE;
theNode->right->right->bottom->logical = logical;
tempNode = theNode->right->right->bottom;
if (theGroup->bottom == NULL)
{ tempNode->right = theGroup; }
else
{
tempNode->right = GetLHSParseNode(theEnv);
tempNode->right->type = AND_CE;
tempNode->right->logical = logical;
tempNode->right->right = theGroup;
}
}
/*================*/
/* Return the CE. */
/*================*/
return(theNode);
}
/***********************************************/
/* GroupPatterns: Groups a series of connected */
/* conditional elements together. */
/***********************************************/
static struct lhsParseNode *GroupPatterns(
void *theEnv,
char *readSource,
int terminator,
char *terminatorString,
int *error)
{
struct lhsParseNode *lastNode, *newNode, *theNode;
lastNode = theNode = NULL;
while (TRUE)
{
/*==================*/
/* Get the next CE. */
/*==================*/
newNode = LHSPattern(theEnv,readSource,terminator,terminatorString,
error,FALSE,NULL,NULL);
/*=======================================================*/
/* If an error occurred, release any LHS data structures */
/* previously allocated by this routine. */
/*=======================================================*/
if (*error)
{
ReturnLHSParseNodes(theEnv,theNode);
return(NULL);
}
/*===============================================*/
/* A NULL value for the CE just parsed indicates */
/* that the terminator for the group of patterns */
/* was encountered (either a "=>" or a ")". */
/*===============================================*/
if (newNode == NULL)
{
PPBackup(theEnv);
PPBackup(theEnv);
if (terminator == RPAREN)
{ SavePPBuffer(theEnv,terminatorString); }
else
{
PPCRAndIndent(theEnv);
SavePPBuffer(theEnv,terminatorString);
}
return(theNode);
}
/*============================*/
/* Add the new CE to the list */
/* of CEs being grouped. */
/*============================*/
if (lastNode == NULL)
{ theNode = newNode; }
else
{ lastNode->bottom = newNode; }
lastNode = newNode;
/*======================================*/
/* Fix the pretty print representation. */
/*======================================*/
PPCRAndIndent(theEnv);
}
}
/**************************************************************/
/* TestPattern: Handles parsing of test conditional elements. */
/* */
/* <test-CE> ::= (test <function-call>) */
/**************************************************************/
static struct lhsParseNode *TestPattern(
void *theEnv,
char *readSource,
int *error)
{
struct lhsParseNode *theNode;
struct token theToken;
struct expr *theExpression;
/*================================================*/
/* Create the data specification for the test CE. */
/*================================================*/
SavePPBuffer(theEnv," ");
theNode = GetLHSParseNode(theEnv);
theNode->type = TEST_CE;
theExpression = Function0Parse(theEnv,readSource);
theNode->expression = ExpressionToLHSParseNodes(theEnv,theExpression);
ReturnExpression(theEnv,theExpression);
if (theNode->expression == NULL)
{
*error = TRUE;
ReturnLHSParseNodes(theEnv,theNode);
return(NULL);
}
/*=========================================================*/
/* Check for the closing right parenthesis of the test CE. */
/*=========================================================*/
GetToken(theEnv,readSource,&theToken);
if (theToken.type != RPAREN)
{
SyntaxErrorMessage(theEnv,"test conditional element");
*error = TRUE;
ReturnLHSParseNodes(theEnv,theNode);
return(NULL);
}
/*=====================*/
/* Return the test CE. */
/*=====================*/
return(theNode);
}
/****************************************************************/
/* AssignmentParse: Finishes the parsing of pattern conditional */
/* elements that have been bound to a variable. */
/* */
/* <assigned-pattern-CE> ::= ?<variable-symbol> <- <pattern-CE> */
/****************************************************************/
static struct lhsParseNode *AssignmentParse(
void *theEnv,
char *readSource,
SYMBOL_HN *factAddress,
int *error)
{
struct lhsParseNode *theNode;
struct token theToken;
/*=====================================================*/
/* Patterns cannot be bound if they are with a not CE. */
/*=====================================================*/
if (PatternData(theEnv)->WithinNotCE)
{
PrintErrorID(theEnv,"RULELHS",2,TRUE);
EnvPrintRouter(theEnv,WERROR,"A pattern CE cannot be bound to a pattern-address within a not CE\n");
*error = TRUE;
return(NULL);
}
/*===============================================*/
/* Check for binder token, "<-", after variable. */
/*===============================================*/
SavePPBuffer(theEnv," ");
GetToken(theEnv,readSource,&theToken);
if ((theToken.type == SYMBOL) ? (strcmp(ValueToString(theToken.value),"<-") != 0) :
TRUE)
{
SyntaxErrorMessage(theEnv,"binding patterns");
*error = TRUE;
return(NULL);
}
SavePPBuffer(theEnv," ");
/*================================================*/
/* Check for opening left parenthesis of pattern. */
/*================================================*/
GetToken(theEnv,readSource,&theToken);
if (theToken.type != LPAREN)
{
SyntaxErrorMessage(theEnv,"binding patterns");
*error = TRUE;
return(NULL);
}
/*======================================================*/
/* Parse the pattern and return the data specification. */
/*======================================================*/
GetToken(theEnv,readSource,&theToken);
theNode = SimplePatternParse(theEnv,readSource,&theToken,error);
if (*error == TRUE)
{
ReturnLHSParseNodes(theEnv,theNode);
return(NULL);
}
/*=============================================*/
/* Store the name of the variable to which the */
/* pattern is bound and return the pattern. */
/*=============================================*/
theNode->value = (void *) factAddress;
return(theNode);
}
/************************************************************/
/* TagLHSLogicalNodes: Marks all *and*, *or*, and *not* CEs */
/* contained within a logical CE as having the properties */
/* associated with a logical CE. */
/************************************************************/
static void TagLHSLogicalNodes(
struct lhsParseNode *nodePtr)
{
while (nodePtr != NULL)
{
nodePtr->logical = TRUE;
if ((nodePtr->type == AND_CE) ||
(nodePtr->type == OR_CE) ||
(nodePtr->type == NOT_CE))
{ TagLHSLogicalNodes(nodePtr->right); }
nodePtr = nodePtr->bottom;
}
}
/***********************************************************/
/* SimplePatternParse: Parses a simple pattern (an opening */
/* parenthesis followed by one or more fields followed */
/* by a closing parenthesis). */
/* */
/* <pattern-CE> ::= <ordered-pattern-CE> | */
/* <template-pattern-CE> */
/***********************************************************/
static struct lhsParseNode *SimplePatternParse(
void *theEnv,
char *readSource,
struct token *theToken,
int *error)
{
struct lhsParseNode *theNode;
struct patternParser *tempParser;
/*=================================================*/
/* The first field of a pattern must be a symbol. */
/* In addition, the symbols ":" and "=" can not */
/* be used because they have special significance. */
/*=================================================*/
if (theToken->type != SYMBOL)
{
SyntaxErrorMessage(theEnv,"the first field of a pattern");
*error = TRUE;
return(NULL);
}
else if ((strcmp(ValueToString(theToken->value),"=") == 0) ||
(strcmp(ValueToString(theToken->value),":") == 0))
{
SyntaxErrorMessage(theEnv,"the field field of a pattern");
*error = TRUE;
return(NULL);
}
/*===============================================*/
/* Construct the topmost node of the pattern CE. */
/*===============================================*/
theNode = GetLHSParseNode(theEnv);
theNode->type = PATTERN_CE;
theNode->negated = FALSE;
/*======================================================*/
/* Search for a pattern parser that claims the pattern. */
/*======================================================*/
for (tempParser = PatternData(theEnv)->ListOfPatternParsers;
tempParser != NULL;
tempParser = tempParser->next)
{
if ((*tempParser->recognizeFunction)((SYMBOL_HN *) theToken->value))
{
theNode->patternType = tempParser;
theNode->right = (*tempParser->parseFunction)(theEnv,readSource,theToken);
if (theNode->right == NULL)
{
*error = TRUE;
ReturnLHSParseNodes(theEnv,theNode);
return(NULL);
}
PropagatePatternType(theNode,tempParser);
return(theNode);
}
}
/*=================================*/
/* If a pattern parser couldn't be */
/* found, then signal an error. */
/*=================================*/
*error = TRUE;
SyntaxErrorMessage(theEnv,"the field field of a pattern");
ReturnLHSParseNodes(theEnv,theNode);
return(NULL);
}
/**************************************************************/
/* PropagatePatternType: Sets the selfPattern field for all */
/* lhsParseNodes in a linked list of those data structures. */
/**************************************************************/
globle void PropagatePatternType(
struct lhsParseNode *theLHS,
struct patternParser *theParser)
{
while (theLHS != NULL)
{
theLHS->patternType = theParser;
if (theLHS->right != NULL) PropagatePatternType(theLHS->right,theParser);
if (theLHS->expression != NULL) PropagatePatternType(theLHS->expression,theParser);
theLHS = theLHS->bottom;
}
}
#endif /* (! RUN_TIME) && (! BLOAD_ONLY) && DEFRULE_CONSTRUCT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -