00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #define _RULELHS_SOURCE_
00023
00024 #include "setup.h"
00025
00026 #if (! RUN_TIME) && (! BLOAD_ONLY) && DEFRULE_CONSTRUCT
00027
00028 #include <stdio.h>
00029 #define _STDIO_INCLUDED_
00030 #include <string.h>
00031
00032 #include "agenda.h"
00033 #include "argacces.h"
00034 #include "constant.h"
00035 #include "constrct.h"
00036 #include "constrnt.h"
00037 #include "cstrnchk.h"
00038 #include "envrnmnt.h"
00039 #include "exprnpsr.h"
00040 #include "memalloc.h"
00041 #include "pattern.h"
00042 #include "reorder.h"
00043 #include "router.h"
00044 #include "ruledef.h"
00045 #include "scanner.h"
00046 #include "symbol.h"
00047
00048 #include "rulelhs.h"
00049
00050
00051
00052
00053
00054 static struct lhsParseNode *RuleBodyParse(void *,char *,struct token *,char *,int *);
00055 static void DeclarationParse(void *,char *,char *,int *);
00056 static struct lhsParseNode *LHSPattern(void *,char *,int,char *,int *,int,
00057 struct token *,char *);
00058 static struct lhsParseNode *ConnectedPatternParse(void *,char *,struct token *,int *);
00059 static struct lhsParseNode *GroupPatterns(void *,char *,int,char *,int *);
00060 static struct lhsParseNode *TestPattern(void *,char *,int *);
00061 static struct lhsParseNode *AssignmentParse(void *,char *,SYMBOL_HN *,int *);
00062 static void TagLHSLogicalNodes(struct lhsParseNode *);
00063 static struct lhsParseNode *SimplePatternParse(void *,char *,struct token *,int *);
00064 static void ParseSalience(void *,char *,char *,int *);
00065 static void ParseAutoFocus(void *,char *,int *);
00066
00067
00068
00069
00070
00071
00072 globle struct lhsParseNode *ParseRuleLHS(
00073 void *theEnv,
00074 char *readSource,
00075 struct token *theToken,
00076 char *ruleName,
00077 int *error)
00078 {
00079 struct lhsParseNode *theLHS;
00080 int result;
00081
00082 *error = FALSE;
00083
00084
00085
00086
00087
00088 PatternData(theEnv)->GlobalSalience = 0;
00089 PatternData(theEnv)->GlobalAutoFocus = FALSE;
00090 PatternData(theEnv)->SalienceExpression = NULL;
00091
00092
00093
00094
00095
00096 SetIndentDepth(theEnv,3);
00097
00098
00099
00100
00101
00102 theLHS = RuleBodyParse(theEnv,readSource,theToken,ruleName,error);
00103
00104 if (*error) return(NULL);
00105
00106
00107
00108
00109
00110
00111
00112 theLHS = ReorderPatterns(theEnv,theLHS,&result);
00113
00114
00115
00116
00117
00118 return(theLHS);
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 static struct lhsParseNode *RuleBodyParse(
00131 void *theEnv,
00132 char *readSource,
00133 struct token *theToken,
00134 char *ruleName,
00135 int *error)
00136 {
00137 struct lhsParseNode *theNode, *otherNodes;
00138
00139
00140
00141
00142
00143 *error = FALSE;
00144
00145
00146
00147
00148
00149
00150 if ((theToken->type == SYMBOL) ?
00151 (strcmp(ValueToString(theToken->value),"=>") == 0) : FALSE)
00152 { return(NULL); }
00153
00154
00155
00156
00157
00158
00159 theNode = LHSPattern(theEnv,readSource,SYMBOL,"=>",error,TRUE,theToken,ruleName);
00160
00161 if (*error == TRUE)
00162 {
00163 ReturnLHSParseNodes(theEnv,theNode);
00164 return(NULL);
00165 }
00166
00167 PPCRAndIndent(theEnv);
00168
00169
00170
00171
00172
00173 otherNodes = GroupPatterns(theEnv,readSource,SYMBOL,"=>",error);
00174
00175 if (*error == TRUE)
00176 {
00177 ReturnLHSParseNodes(theEnv,theNode);
00178 return(NULL);
00179 }
00180
00181
00182
00183
00184
00185
00186 if (theNode == NULL)
00187 { theNode = otherNodes; }
00188 else
00189 { theNode->bottom = otherNodes; }
00190
00191
00192
00193
00194
00195 return(theNode);
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 static void DeclarationParse(
00207 void *theEnv,
00208 char *readSource,
00209 char *ruleName,
00210 int *error)
00211 {
00212 struct token theToken;
00213 struct expr *packPtr;
00214 int notDone = TRUE;
00215 int salienceParsed = FALSE, autoFocusParsed = FALSE;
00216
00217
00218
00219
00220
00221 SavePPBuffer(theEnv," ");
00222
00223 GetToken(theEnv,readSource,&theToken);
00224 if (theToken.type != LPAREN)
00225 {
00226 SyntaxErrorMessage(theEnv,"declare statement");
00227 *error = TRUE;
00228 return;
00229 }
00230
00231
00232
00233
00234
00235
00236 while (notDone)
00237 {
00238
00239
00240
00241
00242 GetToken(theEnv,readSource,&theToken);
00243 if (theToken.type != SYMBOL)
00244 {
00245 SyntaxErrorMessage(theEnv,"declare statement");
00246 *error = TRUE;
00247 }
00248
00249
00250
00251
00252
00253 else if (strcmp(ValueToString(theToken.value),"salience") == 0)
00254 {
00255 if (salienceParsed)
00256 {
00257 AlreadyParsedErrorMessage(theEnv,"salience declaration",NULL);
00258 *error = TRUE;
00259 }
00260 else
00261 {
00262 ParseSalience(theEnv,readSource,ruleName,error);
00263 salienceParsed = TRUE;
00264 }
00265 }
00266
00267
00268
00269
00270
00271
00272
00273 else if (strcmp(ValueToString(theToken.value),"auto-focus") == 0)
00274 {
00275 if (autoFocusParsed)
00276 {
00277 AlreadyParsedErrorMessage(theEnv,"auto-focus declaration",NULL);
00278 *error = TRUE;
00279 }
00280 else
00281 {
00282 ParseAutoFocus(theEnv,readSource,error);
00283 autoFocusParsed = TRUE;
00284 }
00285 }
00286
00287
00288
00289
00290
00291
00292 else
00293 {
00294 SyntaxErrorMessage(theEnv,"declare statement");
00295 *error = TRUE;
00296 }
00297
00298
00299
00300
00301
00302 if (*error)
00303 {
00304 ReturnExpression(theEnv,PatternData(theEnv)->SalienceExpression);
00305 PatternData(theEnv)->SalienceExpression = NULL;
00306 return;
00307 }
00308
00309
00310
00311
00312
00313
00314 GetToken(theEnv,readSource,&theToken);
00315 if (theToken.type != RPAREN)
00316 {
00317 PPBackup(theEnv);
00318 SavePPBuffer(theEnv," ");
00319 SavePPBuffer(theEnv,theToken.printForm);
00320 ReturnExpression(theEnv,PatternData(theEnv)->SalienceExpression);
00321 PatternData(theEnv)->SalienceExpression = NULL;
00322 SyntaxErrorMessage(theEnv,"declare statement");
00323 *error = TRUE;
00324 return;
00325 }
00326
00327
00328
00329
00330
00331 GetToken(theEnv,readSource,&theToken);
00332 if (theToken.type == RPAREN) notDone = FALSE;
00333 else if (theToken.type != LPAREN)
00334 {
00335 ReturnExpression(theEnv,PatternData(theEnv)->SalienceExpression);
00336 PatternData(theEnv)->SalienceExpression = NULL;
00337 SyntaxErrorMessage(theEnv,"declare statement");
00338 *error = TRUE;
00339 return;
00340 }
00341 else
00342 {
00343 PPBackup(theEnv);
00344 SavePPBuffer(theEnv," (");
00345 }
00346 }
00347
00348
00349
00350
00351
00352
00353 packPtr = PackExpression(theEnv,PatternData(theEnv)->SalienceExpression);
00354 ReturnExpression(theEnv,PatternData(theEnv)->SalienceExpression);
00355 PatternData(theEnv)->SalienceExpression = packPtr;
00356 return;
00357 }
00358
00359
00360
00361
00362
00363 static void ParseSalience(
00364 void *theEnv,
00365 char *readSource,
00366 char *ruleName,
00367 int *error)
00368 {
00369 int salience;
00370 DATA_OBJECT salienceValue;
00371
00372
00373
00374
00375
00376 SavePPBuffer(theEnv," ");
00377
00378 PatternData(theEnv)->SalienceExpression = ParseAtomOrExpression(theEnv,readSource,NULL);
00379 if (PatternData(theEnv)->SalienceExpression == NULL)
00380 {
00381 *error = TRUE;
00382 return;
00383 }
00384
00385
00386
00387
00388
00389 SetEvaluationError(theEnv,FALSE);
00390 if (EvaluateExpression(theEnv,PatternData(theEnv)->SalienceExpression,&salienceValue))
00391 {
00392 SalienceInformationError(theEnv,"defrule",ruleName);
00393 *error = TRUE;
00394 return;
00395 }
00396
00397 if (salienceValue.type != INTEGER)
00398 {
00399 SalienceNonIntegerError(theEnv);
00400 *error = TRUE;
00401 return;
00402 }
00403
00404
00405
00406
00407
00408 salience = (int) ValueToLong(salienceValue.value);
00409
00410 if ((salience > MAX_DEFRULE_SALIENCE) || (salience < MIN_DEFRULE_SALIENCE))
00411 {
00412 SalienceRangeError(theEnv,MIN_DEFRULE_SALIENCE,MAX_DEFRULE_SALIENCE);
00413 *error = TRUE;
00414 return;
00415 }
00416
00417
00418
00419
00420
00421
00422 if (PatternData(theEnv)->SalienceExpression->type == INTEGER)
00423 {
00424 ReturnExpression(theEnv,PatternData(theEnv)->SalienceExpression);
00425 PatternData(theEnv)->SalienceExpression = NULL;
00426 }
00427
00428 PatternData(theEnv)->GlobalSalience = salience;
00429 }
00430
00431
00432
00433
00434
00435 static void ParseAutoFocus(
00436 void *theEnv,
00437 char *readSource,
00438 int *error)
00439 {
00440 struct token theToken;
00441
00442
00443
00444
00445
00446 SavePPBuffer(theEnv," ");
00447
00448 GetToken(theEnv,readSource,&theToken);
00449 if (theToken.type != SYMBOL)
00450 {
00451 SyntaxErrorMessage(theEnv,"auto-focus statement");
00452 *error = TRUE;
00453 return;
00454 }
00455
00456
00457
00458
00459
00460
00461
00462 if (strcmp(ValueToString(theToken.value),"TRUE") == 0)
00463 { PatternData(theEnv)->GlobalAutoFocus = TRUE; }
00464 else if (strcmp(ValueToString(theToken.value),"FALSE") == 0)
00465 { PatternData(theEnv)->GlobalAutoFocus = FALSE; }
00466 else
00467 {
00468 SyntaxErrorMessage(theEnv,"auto-focus statement");
00469 *error = TRUE;
00470 }
00471 }
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 static struct lhsParseNode *LHSPattern(
00486 void *theEnv,
00487 char *readSource,
00488 int terminator,
00489 char *terminatorString,
00490 int *error,
00491 int allowDeclaration,
00492 struct token *firstToken,
00493 char *ruleName)
00494 {
00495 struct token theToken;
00496 struct lhsParseNode *theNode;
00497
00498
00499
00500
00501
00502
00503 if (firstToken == NULL) GetToken(theEnv,readSource,&theToken);
00504 else CopyToken(&theToken,firstToken);
00505
00506
00507
00508
00509
00510 if (theToken.type == LPAREN)
00511 {
00512
00513
00514
00515
00516 GetToken(theEnv,readSource,&theToken);
00517 if (theToken.type != SYMBOL)
00518 {
00519 SyntaxErrorMessage(theEnv,"the first field of a pattern");
00520 *error = TRUE;
00521 return(NULL);
00522 }
00523
00524
00525
00526
00527
00528
00529 if (allowDeclaration &&
00530 (strcmp(ValueToString(theToken.value),"declare") == 0))
00531 {
00532 if (ruleName == NULL) SystemError(theEnv,"RULELHS",1);
00533 DeclarationParse(theEnv,readSource,ruleName,error);
00534 theNode = NULL;
00535 }
00536
00537
00538
00539
00540
00541 else if (strcmp(ValueToString(theToken.value),"test") == 0)
00542 { theNode = TestPattern(theEnv,readSource,error); }
00543
00544
00545
00546
00547
00548
00549 else if ((strcmp(ValueToString(theToken.value),"and") == 0) ||
00550 (strcmp(ValueToString(theToken.value),"logical") == 0) ||
00551 (strcmp(ValueToString(theToken.value),"not") == 0) ||
00552 (strcmp(ValueToString(theToken.value),"exists") == 0) ||
00553 (strcmp(ValueToString(theToken.value),"forall") == 0) ||
00554 (strcmp(ValueToString(theToken.value),"or") == 0))
00555 { theNode = ConnectedPatternParse(theEnv,readSource,&theToken,error); }
00556
00557
00558
00559
00560
00561 else
00562 { theNode = SimplePatternParse(theEnv,readSource,&theToken,error); }
00563 }
00564
00565
00566
00567
00568
00569 else if (theToken.type == SF_VARIABLE)
00570 { theNode = AssignmentParse(theEnv,readSource,(SYMBOL_HN *) theToken.value,error); }
00571
00572
00573
00574
00575
00576
00577
00578 else if ((theToken.type == terminator) ?
00579 (strcmp(theToken.printForm,terminatorString) == 0) : FALSE)
00580 { return(NULL); }
00581
00582
00583
00584
00585
00586 else
00587 {
00588 SyntaxErrorMessage(theEnv,"defrule");
00589 *error = TRUE;
00590 return(NULL);
00591 }
00592
00593
00594
00595
00596
00597
00598 if (*error == TRUE)
00599 {
00600 ReturnLHSParseNodes(theEnv,theNode);
00601 return(NULL);
00602 }
00603
00604
00605
00606
00607
00608 return(theNode);
00609 }
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634 static struct lhsParseNode *ConnectedPatternParse(
00635 void *theEnv,
00636 char *readSource,
00637 struct token *theToken,
00638 int *error)
00639 {
00640 unsigned short connectorValue = 0;
00641 struct lhsParseNode *theNode, *tempNode, *theGroup;
00642 char *errorCE = NULL;
00643 int logical = FALSE;
00644 int tempValue;
00645
00646
00647
00648
00649
00650 IncrementIndentDepth(theEnv,5);
00651 if (strcmp(ValueToString(theToken->value),"or") == 0)
00652 {
00653 connectorValue = OR_CE;
00654 errorCE = "the or conditional element";
00655 SavePPBuffer(theEnv," ");
00656 }
00657 else if (strcmp(ValueToString(theToken->value),"and") == 0)
00658 {
00659 connectorValue = AND_CE;
00660 errorCE = "the and conditional element";
00661 SavePPBuffer(theEnv," ");
00662 }
00663 else if (strcmp(ValueToString(theToken->value),"not") == 0)
00664 {
00665 connectorValue = NOT_CE;
00666 errorCE = "the not conditional element";
00667 SavePPBuffer(theEnv," ");
00668 }
00669 else if (strcmp(ValueToString(theToken->value),"exists") == 0)
00670 {
00671 connectorValue = EXISTS_CE;
00672 errorCE = "the exists conditional element";
00673 PPCRAndIndent(theEnv);
00674 }
00675 else if (strcmp(ValueToString(theToken->value),"forall") == 0)
00676 {
00677 connectorValue = FORALL_CE;
00678 errorCE = "the forall conditional element";
00679 PPCRAndIndent(theEnv);
00680 }
00681 else if (strcmp(ValueToString(theToken->value),"logical") == 0)
00682 {
00683 connectorValue = AND_CE;
00684 errorCE = "the logical conditional element";
00685 logical = TRUE;
00686 PPCRAndIndent(theEnv);
00687 }
00688
00689
00690
00691
00692
00693 if (PatternData(theEnv)->WithinNotCE && logical)
00694 {
00695 PrintErrorID(theEnv,"RULELHS",1,TRUE);
00696 EnvPrintRouter(theEnv,WERROR,"The logical CE cannot be used within a not/exists/forall CE.\n");
00697 *error = TRUE;
00698 return(NULL);
00699 }
00700
00701
00702
00703
00704
00705
00706 tempValue = PatternData(theEnv)->WithinNotCE;
00707 if ((connectorValue == NOT_CE) ||
00708 (connectorValue == EXISTS_CE) ||
00709 (connectorValue == FORALL_CE))
00710 { PatternData(theEnv)->WithinNotCE = TRUE; }
00711
00712
00713
00714
00715
00716
00717 theGroup = GroupPatterns(theEnv,readSource,RPAREN,")",error);
00718
00719
00720
00721
00722
00723
00724 PatternData(theEnv)->WithinNotCE = tempValue;
00725 DecrementIndentDepth(theEnv,5);
00726
00727
00728
00729
00730
00731 if (*error == TRUE)
00732 {
00733 ReturnLHSParseNodes(theEnv,theGroup);
00734 return(NULL);
00735 }
00736
00737
00738
00739
00740
00741
00742 if (logical) TagLHSLogicalNodes(theGroup);
00743
00744
00745
00746
00747
00748 if (theGroup == NULL)
00749 {
00750 SyntaxErrorMessage(theEnv,errorCE);
00751 *error = TRUE;
00752 return(NULL);
00753 }
00754
00755
00756
00757
00758
00759 if ((connectorValue == NOT_CE) && (theGroup->bottom != NULL))
00760 {
00761 SyntaxErrorMessage(theEnv,errorCE);
00762 ReturnLHSParseNodes(theEnv,theGroup);
00763 *error = TRUE;
00764 return(NULL);
00765 }
00766
00767
00768
00769
00770
00771 if ((connectorValue == FORALL_CE) && (theGroup->bottom == NULL))
00772 {
00773 SyntaxErrorMessage(theEnv,errorCE);
00774 ReturnLHSParseNodes(theEnv,theGroup);
00775 *error = TRUE;
00776 return(NULL);
00777 }
00778
00779
00780
00781
00782
00783 if (((connectorValue == AND_CE) || (connectorValue == OR_CE)) &&
00784 (theGroup->bottom == NULL))
00785 {
00786 theGroup->logical = logical;
00787 return(theGroup);
00788 }
00789
00790
00791
00792
00793
00794 theNode = GetLHSParseNode(theEnv);
00795 theNode->logical = logical;
00796
00797
00798
00799
00800
00801 if ((connectorValue == AND_CE) ||
00802 (connectorValue == OR_CE) ||
00803 (connectorValue == NOT_CE))
00804 {
00805 theNode->type = connectorValue;
00806 theNode->right = theGroup;
00807 }
00808
00809
00810
00811
00812
00813 else if (connectorValue == EXISTS_CE)
00814 {
00815 theNode->type = NOT_CE;
00816
00817 theNode->right = GetLHSParseNode(theEnv);
00818 theNode->right->type = NOT_CE;
00819 theNode->right->logical = logical;
00820
00821 if (theGroup->bottom != NULL)
00822 {
00823 theNode->right->right = GetLHSParseNode(theEnv);
00824 theNode->right->right->type = AND_CE;
00825 theNode->right->right->logical = logical;
00826 theNode->right->right->right = theGroup;
00827 }
00828 else
00829 { theNode->right->right = theGroup; }
00830 }
00831
00832
00833
00834
00835
00836
00837 else if (connectorValue == FORALL_CE)
00838 {
00839 theNode->type = NOT_CE;
00840
00841 tempNode = theGroup->bottom;
00842 theGroup->bottom = NULL;
00843
00844 theNode->right = GetLHSParseNode(theEnv);
00845 theNode->right->type = AND_CE;
00846 theNode->right->logical = logical;
00847 theNode->right->right = theGroup;
00848
00849 theGroup = tempNode;
00850
00851 theNode->right->right->bottom = GetLHSParseNode(theEnv);
00852 theNode->right->right->bottom->type = NOT_CE;
00853 theNode->right->right->bottom->logical = logical;
00854
00855 tempNode = theNode->right->right->bottom;
00856
00857 if (theGroup->bottom == NULL)
00858 { tempNode->right = theGroup; }
00859 else
00860 {
00861 tempNode->right = GetLHSParseNode(theEnv);
00862 tempNode->right->type = AND_CE;
00863 tempNode->right->logical = logical;
00864 tempNode->right->right = theGroup;
00865 }
00866 }
00867
00868
00869
00870
00871
00872 return(theNode);
00873 }
00874
00875
00876
00877
00878
00879 static struct lhsParseNode *GroupPatterns(
00880 void *theEnv,
00881 char *readSource,
00882 int terminator,
00883 char *terminatorString,
00884 int *error)
00885 {
00886 struct lhsParseNode *lastNode, *newNode, *theNode;
00887
00888 lastNode = theNode = NULL;
00889
00890 while (TRUE)
00891 {
00892
00893
00894
00895
00896 newNode = LHSPattern(theEnv,readSource,terminator,terminatorString,
00897 error,FALSE,NULL,NULL);
00898
00899
00900
00901
00902
00903
00904 if (*error)
00905 {
00906 ReturnLHSParseNodes(theEnv,theNode);
00907 return(NULL);
00908 }
00909
00910
00911
00912
00913
00914
00915
00916 if (newNode == NULL)
00917 {
00918 PPBackup(theEnv);
00919 PPBackup(theEnv);
00920 if (terminator == RPAREN)
00921 { SavePPBuffer(theEnv,terminatorString); }
00922 else
00923 {
00924 PPCRAndIndent(theEnv);
00925 SavePPBuffer(theEnv,terminatorString);
00926 }
00927
00928 return(theNode);
00929 }
00930
00931
00932
00933
00934
00935
00936 if (lastNode == NULL)
00937 { theNode = newNode; }
00938 else
00939 { lastNode->bottom = newNode; }
00940
00941 lastNode = newNode;
00942
00943
00944
00945
00946
00947 PPCRAndIndent(theEnv);
00948 }
00949 }
00950
00951
00952
00953
00954
00955
00956 static struct lhsParseNode *TestPattern(
00957 void *theEnv,
00958 char *readSource,
00959 int *error)
00960 {
00961 struct lhsParseNode *theNode;
00962 struct token theToken;
00963 struct expr *theExpression;
00964
00965
00966
00967
00968
00969 SavePPBuffer(theEnv," ");
00970 theNode = GetLHSParseNode(theEnv);
00971 theNode->type = TEST_CE;
00972 theExpression = Function0Parse(theEnv,readSource);
00973 theNode->expression = ExpressionToLHSParseNodes(theEnv,theExpression);
00974 ReturnExpression(theEnv,theExpression);
00975
00976 if (theNode->expression == NULL)
00977 {
00978 *error = TRUE;
00979 ReturnLHSParseNodes(theEnv,theNode);
00980 return(NULL);
00981 }
00982
00983
00984
00985
00986
00987 GetToken(theEnv,readSource,&theToken);
00988 if (theToken.type != RPAREN)
00989 {
00990 SyntaxErrorMessage(theEnv,"test conditional element");
00991 *error = TRUE;
00992 ReturnLHSParseNodes(theEnv,theNode);
00993 return(NULL);
00994 }
00995
00996
00997
00998
00999
01000 return(theNode);
01001 }
01002
01003
01004
01005
01006
01007
01008
01009 static struct lhsParseNode *AssignmentParse(
01010 void *theEnv,
01011 char *readSource,
01012 SYMBOL_HN *factAddress,
01013 int *error)
01014 {
01015 struct lhsParseNode *theNode;
01016 struct token theToken;
01017
01018
01019
01020
01021
01022 if (PatternData(theEnv)->WithinNotCE)
01023 {
01024 PrintErrorID(theEnv,"RULELHS",2,TRUE);
01025 EnvPrintRouter(theEnv,WERROR,"A pattern CE cannot be bound to a pattern-address within a not CE\n");
01026 *error = TRUE;
01027 return(NULL);
01028 }
01029
01030
01031
01032
01033
01034 SavePPBuffer(theEnv," ");
01035
01036 GetToken(theEnv,readSource,&theToken);
01037
01038 if ((theToken.type == SYMBOL) ? (strcmp(ValueToString(theToken.value),"<-") != 0) :
01039 TRUE)
01040 {
01041 SyntaxErrorMessage(theEnv,"binding patterns");
01042 *error = TRUE;
01043 return(NULL);
01044 }
01045
01046 SavePPBuffer(theEnv," ");
01047
01048
01049
01050
01051
01052 GetToken(theEnv,readSource,&theToken);
01053 if (theToken.type != LPAREN)
01054 {
01055 SyntaxErrorMessage(theEnv,"binding patterns");
01056 *error = TRUE;
01057 return(NULL);
01058 }
01059
01060
01061
01062
01063
01064 GetToken(theEnv,readSource,&theToken);
01065
01066 theNode = SimplePatternParse(theEnv,readSource,&theToken,error);
01067
01068 if (*error == TRUE)
01069 {
01070 ReturnLHSParseNodes(theEnv,theNode);
01071 return(NULL);
01072 }
01073
01074
01075
01076
01077
01078
01079 theNode->value = (void *) factAddress;
01080 return(theNode);
01081 }
01082
01083
01084
01085
01086
01087
01088 static void TagLHSLogicalNodes(
01089 struct lhsParseNode *nodePtr)
01090 {
01091 while (nodePtr != NULL)
01092 {
01093 nodePtr->logical = TRUE;
01094 if ((nodePtr->type == AND_CE) ||
01095 (nodePtr->type == OR_CE) ||
01096 (nodePtr->type == NOT_CE))
01097 { TagLHSLogicalNodes(nodePtr->right); }
01098 nodePtr = nodePtr->bottom;
01099 }
01100 }
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110 static struct lhsParseNode *SimplePatternParse(
01111 void *theEnv,
01112 char *readSource,
01113 struct token *theToken,
01114 int *error)
01115 {
01116 struct lhsParseNode *theNode;
01117 struct patternParser *tempParser;
01118
01119
01120
01121
01122
01123
01124
01125 if (theToken->type != SYMBOL)
01126 {
01127 SyntaxErrorMessage(theEnv,"the first field of a pattern");
01128 *error = TRUE;
01129 return(NULL);
01130 }
01131 else if ((strcmp(ValueToString(theToken->value),"=") == 0) ||
01132 (strcmp(ValueToString(theToken->value),":") == 0))
01133 {
01134 SyntaxErrorMessage(theEnv,"the field field of a pattern");
01135 *error = TRUE;
01136 return(NULL);
01137 }
01138
01139
01140
01141
01142
01143 theNode = GetLHSParseNode(theEnv);
01144 theNode->type = PATTERN_CE;
01145 theNode->negated = FALSE;
01146 theNode->exists = FALSE;
01147
01148
01149
01150
01151
01152 for (tempParser = PatternData(theEnv)->ListOfPatternParsers;
01153 tempParser != NULL;
01154 tempParser = tempParser->next)
01155 {
01156 if ((*tempParser->recognizeFunction)((SYMBOL_HN *) theToken->value))
01157 {
01158 theNode->patternType = tempParser;
01159 theNode->right = (*tempParser->parseFunction)(theEnv,readSource,theToken);
01160 if (theNode->right == NULL)
01161 {
01162 *error = TRUE;
01163 ReturnLHSParseNodes(theEnv,theNode);
01164 return(NULL);
01165 }
01166
01167 PropagatePatternType(theNode,tempParser);
01168 return(theNode);
01169 }
01170 }
01171
01172
01173
01174
01175
01176
01177 *error = TRUE;
01178 SyntaxErrorMessage(theEnv,"the field field of a pattern");
01179 ReturnLHSParseNodes(theEnv,theNode);
01180 return(NULL);
01181 }
01182
01183
01184
01185
01186
01187 globle void PropagatePatternType(
01188 struct lhsParseNode *theLHS,
01189 struct patternParser *theParser)
01190 {
01191 while (theLHS != NULL)
01192 {
01193 theLHS->patternType = theParser;
01194 if (theLHS->right != NULL) PropagatePatternType(theLHS->right,theParser);
01195 if (theLHS->expression != NULL) PropagatePatternType(theLHS->expression,theParser);
01196 theLHS = theLHS->bottom;
01197 }
01198 }
01199
01200 #endif
01201
01202