home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / APPS / hl10osrc.zoo / Lib / ParseExpr.y < prev    next >
Text File  |  2009-11-06  |  7KB  |  289 lines

  1. /* -*- Mode: C -*- */
  2. /* ParseExpr.y - Paser for -only expressions (used by print functions)
  3.  * Created by Robert Heller on Fri Feb 28 23:20:45 1992
  4.  *
  5.  * ------------------------------------------------------------------
  6.  * Home Libarian by Deepwoods Software
  7.  * Common Class library implementation code
  8.  * ------------------------------------------------------------------
  9.  * Modification History:
  10.  * ------------------------------------------------------------------
  11.  * Contents:
  12.  * ------------------------------------------------------------------
  13.  * 
  14.  * 
  15.  * Copyright (c) 1991,1992 by Robert heller (D/B/A Deepwoods Software)
  16.  *        All Rights Reserved
  17.  * 
  18.  */
  19.  
  20. %{
  21. #include <stream.h>
  22. #include <common.h>
  23. #include <ctype.h>
  24. #include <Card.h>
  25. #include <PTree.h>
  26.  
  27. static Tree* result = 0;
  28.  
  29. static const struct {
  30.     const char* n;
  31.     Fields f;
  32. } FieldNames[] = {
  33.     { "TYPE", TypeField },
  34.     { "AUTHOR", AuthorField },
  35.     { "TITLE", TitleField },
  36.     { "PUBLISHER", PublisherField },
  37.     { "CITY", CityField },
  38.     { "VOLUME", VolumeField },
  39.     { "YEAR", YearField }
  40. };
  41.  
  42. const NumFields = sizeof(FieldNames) / sizeof(FieldNames[0]);
  43.  
  44. enum TypeErrors {OK, TyOK, NoConstant, NoField, MisMatch};
  45.  
  46. static TypeErrors TypeCheck(Node* a, Node* b)
  47. {
  48.     if (a->type == FieldNode && b->type == FieldNode) return(NoConstant);
  49.     else if (a->type != FieldNode && b->type != FieldNode) return(NoField);
  50.     else if (a->type != FieldNode) return(TypeCheck(b,a));
  51.     else switch (a->value._field) {
  52.         case TypeField: if (b->type == CardTypeNode) return(TyOK);
  53.                 else return(MisMatch);
  54.                 break;
  55.         case AuthorField:
  56.         case TitleField:
  57.         case PublisherField:
  58.         case CityField:    if (b->type == StringNode) return(OK);
  59.                 else return(MisMatch);
  60.                 break;
  61.         case VolumeField:
  62.         case YearField:    if (b->type == IntNode) return(OK);
  63.                 else return(MisMatch);
  64.                 break;
  65.     }
  66. }
  67.  
  68. #define MakeNode(v) (new Node(v))
  69. #define MakeTree(o,l,r) (new Tree(o,l,r))
  70.  
  71. #if YYDEBUG != 0
  72. int yydebug = 0;
  73. #endif
  74.  
  75. %}
  76.  
  77. %start result
  78.  
  79. %union {
  80.     int ival;
  81.     char* sval;
  82.     Fields fval;
  83.     CardType tval;
  84.     Tree* trval;
  85.     Node* nval;
  86. }
  87.  
  88. %token <ival> INTEGER
  89. %token <sval> STRING
  90. %token <fval> FIELD
  91. %token <tval> CARDTYPE
  92. %token BADWORD
  93. %type <nval> term
  94. %type <trval> expression
  95.  
  96. %token NOTEQ LESSEQ GREATEREQ
  97. %nonassoc '<' '>' '=' NOTEQ LESSEQ GREATEREQ
  98. %left '&' '|'
  99. %right '!'
  100.  
  101. %%
  102.  
  103. result :    expression
  104.             { result = $1; }
  105.        ;
  106.  
  107. expression : '(' expression ')'
  108.             { $$ = $2; }
  109.        | '!' expression
  110.             { $$ = MakeTree(Not,MakeNode($2),0); }
  111.        | expression '|' expression
  112.             { $$ = MakeTree(Or,MakeNode($1),MakeNode($3)); }
  113.        | expression '&' expression
  114.             { $$ = MakeTree(And,MakeNode($1),MakeNode($3)); }
  115.        | term '=' term
  116.             {
  117.                 switch (TypeCheck($1,$3)) {
  118.                     case NoConstant: yyerror("Missing constant!");
  119.                              YYABORT;
  120.                     case NoField: yyerror("Missing field!");
  121.                               YYABORT;
  122.                     case MisMatch: yyerror("Type mismatch!");
  123.                                YYABORT;
  124.                     case TyOK:
  125.                     case OK: $$ = MakeTree(Equal,$1,$3);
  126.                 }
  127.             }
  128.        | term NOTEQ term
  129.             {
  130.                 switch (TypeCheck($1,$3)) {
  131.                     case NoConstant: yyerror("Missing constant!");
  132.                              YYABORT;
  133.                     case NoField: yyerror("Missing field!");
  134.                               YYABORT;
  135.                     case MisMatch: yyerror("Type mismatch!");
  136.                                YYABORT;
  137.                     case TyOK:
  138.                     case OK: $$ = MakeTree(NotEqual,$1,$3);
  139.                 }
  140.             }
  141.        | term '<' term
  142.             {
  143.                 switch (TypeCheck($1,$3)) {
  144.                     case NoConstant: yyerror("Missing constant!");
  145.                              YYABORT;
  146.                     case NoField: yyerror("Missing field!");
  147.                               YYABORT;
  148.                     case MisMatch: yyerror("Type mismatch!");
  149.                                YYABORT;
  150.                     case TyOK: yyerror("< not allowed for Type");
  151.                            YYABORT;
  152.                     case OK: $$ = MakeTree(Less,$1,$3);
  153.                 }
  154.             }
  155.        | term '>' term
  156.             {
  157.                 switch (TypeCheck($1,$3)) {
  158.                     case NoConstant: yyerror("Missing constant!");
  159.                              YYABORT;
  160.                     case NoField: yyerror("Missing field!");
  161.                               YYABORT;
  162.                     case MisMatch: yyerror("Type mismatch!");
  163.                                YYABORT;
  164.                     case TyOK: yyerror("> not allowed for Type");
  165.                            YYABORT;
  166.                     case OK: $$ = MakeTree(Greater,$1,$3);
  167.                 }
  168.             }
  169.        | term LESSEQ term
  170.             {
  171.                 switch (TypeCheck($1,$3)) {
  172.                     case NoConstant: yyerror("Missing constant!");
  173.                              YYABORT;
  174.                     case NoField: yyerror("Missing field!");
  175.                               YYABORT;
  176.                     case MisMatch: yyerror("Type mismatch!");
  177.                                YYABORT;
  178.                     case TyOK: yyerror("<= not allowed for Type");
  179.                            YYABORT;
  180.                     case OK: $$ = MakeTree(LessEqual,$1,$3);
  181.                 }
  182.             }
  183.        | term GREATEREQ term
  184.             {
  185.                 switch (TypeCheck($1,$3)) {
  186.                     case NoConstant: yyerror("Missing constant!");
  187.                              YYABORT;
  188.                     case NoField: yyerror("Missing field!");
  189.                               YYABORT;
  190.                     case MisMatch: yyerror("Type mismatch!");
  191.                                YYABORT;
  192.                     case TyOK: yyerror(">= not allowed for Type");
  193.                            YYABORT;
  194.                     case OK: $$ = MakeTree(GreaterEqual,$1,$3);
  195.                 }
  196.             }
  197.     ;
  198.  
  199. term : STRING
  200.             { $$ = MakeNode($1); }
  201.      | INTEGER
  202.             { $$ = MakeNode($1); }
  203.      | FIELD
  204.                  { $$ = MakeNode($1); }
  205.      | CARDTYPE
  206.                  { $$ = MakeNode($1); }
  207.      | BADWORD
  208.                  { yyerror("Unknown word"); YYABORT; }
  209.      ;
  210.  
  211. %%
  212.  
  213. static char* original;
  214. static char* curpointer;
  215.  
  216. Tree* ParseOnly(char* string)
  217. {
  218.     ParseExpr parser;
  219.     original = string;
  220.     curpointer = original;
  221.     if (parser.yyparse() == 0) return(result);
  222.     else return(0);
  223. }
  224.  
  225. void ParseExpr::yyerror(char* message)
  226. {
  227.     cout << message << "\n";
  228.     cout << original << "\n";
  229.     for (int pos = curpointer-original; pos > 0; pos--) cout << '.';
  230.     cout << "^\n";
  231. }
  232.  
  233. int ParseExpr::yylex()
  234. {
  235.     static char word[256];
  236.     
  237.     while (*curpointer != 0 && *curpointer <= ' ') curpointer++;
  238.     if (*curpointer == 0) return(YYEOF);
  239.     else if (isdigit(*curpointer)) {
  240.         char* p = word;
  241.         while (isdigit(*curpointer)) *p++ = *curpointer++;
  242.         *p++ = 0;
  243.         yylval.ival = atoi(word);
  244.         return(INTEGER);
  245.     } else if (*curpointer == '"') {
  246.         curpointer++;
  247.         char* p = word;
  248.         while (*curpointer != '"') {
  249.             if (*curpointer == '\\') curpointer++;
  250.             *p++ = *curpointer++;
  251.         }
  252.         curpointer++;
  253.         *p++ = 0;
  254.         yylval.sval = new char[strlen(word)+1];
  255.         strcpy(yylval.sval,word);
  256.         return(STRING);
  257.     } else if (isalpha(*curpointer)) {
  258.         char* p = word;
  259.         while (isalpha(*curpointer)) {
  260.             char c = *curpointer++;
  261.             if (islower(c)) *p++ = toupper(c);
  262.             else *p++ = c;
  263.         }
  264.         *p++ = 0;
  265.         if (CardTypeNameP(word)) {
  266.             yylval.tval = NameType(word);
  267.             return(CARDTYPE);
  268.         } else {
  269.             for (int i = 0; i < NumFields; i++) {
  270.                 if (strcmp(word,FieldNames[i].n) == 0) {
  271.                     yylval.fval = FieldNames[i].f;
  272.                     return(FIELD);
  273.                 }
  274.             }
  275.             return(BADWORD);
  276.         }
  277.     } else if (*curpointer == '!' && *(curpointer+1) == '=') {
  278.         curpointer += 2;
  279.         return(NOTEQ);
  280.     } else if (*curpointer == '<' && *(curpointer+1) == '=') {
  281.         curpointer += 2;
  282.         return(LESSEQ);
  283.     } else if (*curpointer == '>' && *(curpointer+1) == '=') {
  284.         curpointer += 2;
  285.         return(GREATEREQ);
  286.     } else return(*curpointer++);
  287. }
  288.  
  289.