00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #define _TMPLTLHS_SOURCE_
00024
00025 #include "setup.h"
00026
00027 #if DEFTEMPLATE_CONSTRUCT && DEFRULE_CONSTRUCT && (! RUN_TIME) && (! BLOAD_ONLY)
00028
00029 #include <stdio.h>
00030 #define _STDIO_INCLUDED_
00031 #include <string.h>
00032
00033 #include "constant.h"
00034 #include "envrnmnt.h"
00035 #include "memalloc.h"
00036 #include "symbol.h"
00037 #include "scanner.h"
00038 #include "exprnpsr.h"
00039 #include "router.h"
00040 #include "constrnt.h"
00041 #include "constrct.h"
00042 #include "reorder.h"
00043 #include "pattern.h"
00044 #include "factrhs.h"
00045 #include "modulutl.h"
00046 #include "tmpltutl.h"
00047 #include "tmpltdef.h"
00048
00049 #include "tmpltlhs.h"
00050
00051
00052
00053
00054
00055 static struct lhsParseNode *GetLHSSlots(void *,char *,struct token *,struct deftemplate *,int *);
00056 static struct lhsParseNode *GetSingleLHSSlot(void *,char *,struct token *,
00057 struct templateSlot *,int *,short);
00058 static intBool MultiplyDefinedLHSSlots(void *,struct lhsParseNode *,SYMBOL_HN *);
00059
00060
00061
00062
00063
00064 globle struct lhsParseNode *DeftemplateLHSParse(
00065 void *theEnv,
00066 char *readSource,
00067 struct deftemplate *theDeftemplate)
00068 {
00069 struct lhsParseNode *head, *firstSlot;
00070 struct token theToken;
00071 int error;
00072
00073
00074
00075
00076
00077 GetToken(theEnv,readSource,&theToken);
00078 if ((theToken.type == OR_CONSTRAINT) || (theToken.type == AND_CONSTRAINT))
00079 {
00080 SyntaxErrorMessage(theEnv,"deftemplate patterns");
00081 return(NULL);
00082 }
00083
00084
00085
00086
00087
00088 head = GetLHSParseNode(theEnv);
00089 head->type = SF_WILDCARD;
00090 head->negated = FALSE;
00091 head->exists = FALSE;
00092 head->index = 0;
00093 head->slotNumber = 1;
00094 head->bottom = GetLHSParseNode(theEnv);
00095 head->bottom->type = SYMBOL;
00096 head->bottom->negated = FALSE;
00097 head->bottom->exists = FALSE;
00098 head->bottom->value = (void *) theDeftemplate->header.name;
00099
00100
00101
00102
00103
00104 error = FALSE;
00105 firstSlot = GetLHSSlots(theEnv,readSource,&theToken,theDeftemplate,&error);
00106 if (error)
00107 {
00108 ReturnLHSParseNodes(theEnv,firstSlot);
00109 ReturnLHSParseNodes(theEnv,head);
00110 return(NULL);
00111 }
00112
00113
00114
00115
00116
00117 head->right = firstSlot;
00118 return(head);
00119 }
00120
00121
00122
00123
00124
00125 static struct lhsParseNode *GetLHSSlots(
00126 void *theEnv,
00127 char *readSource,
00128 struct token *tempToken,
00129 struct deftemplate *theDeftemplate,
00130 int *error)
00131 {
00132 struct lhsParseNode *firstSlot = NULL, *nextSlot, *lastSlot = NULL;
00133 struct templateSlot *slotPtr;
00134 short position;
00135
00136
00137
00138
00139
00140
00141 while (tempToken->type != RPAREN)
00142 {
00143 PPBackup(theEnv);
00144 SavePPBuffer(theEnv," ");
00145 SavePPBuffer(theEnv,tempToken->printForm);
00146
00147
00148
00149
00150
00151 if (tempToken->type != LPAREN)
00152 {
00153 *error = TRUE;
00154 SyntaxErrorMessage(theEnv,"deftemplate patterns");
00155 ReturnLHSParseNodes(theEnv,firstSlot);
00156 return(NULL);
00157 }
00158
00159
00160
00161
00162
00163 GetToken(theEnv,readSource,tempToken);
00164 if (tempToken->type != SYMBOL)
00165 {
00166 *error = TRUE;
00167 SyntaxErrorMessage(theEnv,"deftemplate patterns");
00168 ReturnLHSParseNodes(theEnv,firstSlot);
00169 return(NULL);
00170 }
00171
00172
00173
00174
00175
00176 if ((slotPtr = FindSlot(theDeftemplate,(SYMBOL_HN *) tempToken->value,&position)) == NULL)
00177 {
00178 *error = TRUE;
00179 InvalidDeftemplateSlotMessage(theEnv,ValueToString(tempToken->value),
00180 ValueToString(theDeftemplate->header.name),TRUE);
00181 ReturnLHSParseNodes(theEnv,firstSlot);
00182 return(NULL);
00183 }
00184
00185
00186
00187
00188
00189 if (MultiplyDefinedLHSSlots(theEnv,firstSlot,(SYMBOL_HN *) tempToken->value) == TRUE)
00190 {
00191 *error = TRUE;
00192 ReturnLHSParseNodes(theEnv,firstSlot);
00193 return(NULL);
00194 }
00195
00196
00197
00198
00199
00200 nextSlot = GetSingleLHSSlot(theEnv,readSource,tempToken,slotPtr,error,(short) (position+1));
00201 if (*error)
00202 {
00203 ReturnLHSParseNodes(theEnv,firstSlot);
00204 ReturnLHSParseNodes(theEnv,nextSlot);
00205 return(NULL);
00206 }
00207
00208
00209
00210
00211
00212
00213 if (lastSlot == NULL)
00214 { firstSlot = nextSlot; }
00215 else
00216 { lastSlot->right = nextSlot; }
00217
00218 while (nextSlot->right != NULL) nextSlot = nextSlot->right;
00219 lastSlot = nextSlot;
00220
00221
00222
00223
00224
00225 GetToken(theEnv,readSource,tempToken);
00226 }
00227
00228
00229
00230
00231
00232 return(firstSlot);
00233 }
00234
00235
00236
00237
00238
00239 static struct lhsParseNode *GetSingleLHSSlot(
00240 void *theEnv,
00241 char *readSource,
00242 struct token *tempToken,
00243 struct templateSlot *slotPtr,
00244 int *error,
00245 short position)
00246 {
00247 struct lhsParseNode *nextSlot;
00248 SYMBOL_HN *slotName;
00249
00250
00251
00252
00253
00254 slotName = (SYMBOL_HN *) tempToken->value;
00255 SavePPBuffer(theEnv," ");
00256 GetToken(theEnv,readSource,tempToken);
00257
00258
00259
00260
00261
00262 if (slotPtr->multislot == FALSE)
00263 {
00264
00265
00266
00267
00268 nextSlot = RestrictionParse(theEnv,readSource,tempToken,FALSE,
00269 slotPtr->slotName,(short) (position - 1),
00270 slotPtr->constraints,0);
00271 if (nextSlot == NULL)
00272 {
00273 *error = TRUE;
00274 return(NULL);
00275 }
00276
00277
00278
00279
00280
00281
00282 if ((nextSlot->type == MF_VARIABLE) ||
00283 (nextSlot->type == MULTIFIELD))
00284 {
00285 SingleFieldSlotCardinalityError(theEnv,slotPtr->slotName->contents);
00286 *error = TRUE;
00287 ReturnLHSParseNodes(theEnv,nextSlot);
00288 return(NULL);
00289 }
00290 }
00291
00292
00293
00294
00295
00296 else
00297 {
00298 nextSlot = RestrictionParse(theEnv,readSource,tempToken,TRUE,slotName,(short) (position - 1),
00299 slotPtr->constraints,1);
00300 if (nextSlot == NULL)
00301 {
00302 *error = TRUE;
00303 return(NULL);
00304 }
00305 }
00306
00307
00308
00309
00310
00311 if (tempToken->type != RPAREN)
00312 {
00313 PPBackup(theEnv);
00314 SavePPBuffer(theEnv," ");
00315 SavePPBuffer(theEnv,tempToken->printForm);
00316 SyntaxErrorMessage(theEnv,"deftemplate patterns");
00317 *error = TRUE;
00318 ReturnLHSParseNodes(theEnv,nextSlot);
00319 return(NULL);
00320 }
00321
00322
00323
00324
00325
00326
00327 if ((nextSlot->bottom == NULL) && slotPtr->multislot)
00328 {
00329 PPBackup(theEnv);
00330 PPBackup(theEnv);
00331 SavePPBuffer(theEnv,")");
00332 }
00333
00334
00335
00336
00337
00338
00339 return(nextSlot);
00340 }
00341
00342
00343
00344
00345
00346 static intBool MultiplyDefinedLHSSlots(
00347 void *theEnv,
00348 struct lhsParseNode *theSlots,
00349 SYMBOL_HN *slotName)
00350 {
00351 for (;
00352 theSlots != NULL;
00353 theSlots = theSlots->right)
00354 {
00355 if (theSlots->slot == slotName)
00356 {
00357 AlreadyParsedErrorMessage(theEnv,"slot ",ValueToString(slotName));
00358 return(TRUE);
00359 }
00360 }
00361
00362 return(FALSE);
00363 }
00364
00365 #endif
00366
00367