ifparse.y
上传用户:aidanglao
上传日期:2007-01-07
资源大小:69k
文件大小:8k
源码类别:

Oracle数据库

开发平台:

Unix_Linux

  1. %{
  2. /* ifparse.y - EXPR Parser
  3. /*
  4. /* Copyright (c) 1995-1999 Applied Information Technologies, Inc.
  5. /* All Rights Reserved.
  6. /*  
  7. /* Distributed uder the GNU General Public License which was included in
  8. /* the file named "LICENSE" in the package that you recieved.
  9. /* If not, write to:
  10. /* The Free Software Foundation, Inc.,
  11. /* 675 Mass Ave, Cambridge, MA 02139, USA.
  12.  */
  13. #include "scalar.h"
  14. #include "boolean.h"
  15. #include "ifwords.h"
  16. /* 
  17. /* The Global Variables for the IfParser
  18.  */
  19. static eBoolean_t gbIfResult; /* The Answer */
  20. static char       *gpIfExpr; /* The Expression to Parse */
  21. static int        giRestart = 0; /* Start a new expression */
  22. %}
  23. %union {
  24.     eBoolean_t bVal; /* Boolean Value eTrue or eFalse */
  25.     Scalar_t *pScalar; /* Scalar Variable */
  26. }
  27. %token IF AND OR NOT BETWEEN LIKE IS NULLX TRUEX FALSEX IN ASSIGN CAT
  28. %token COMPARISON LT GT LE GE EQ NEQ
  29. %token STRING INTNUM APPROXNUM FUNCNAME LITERAL TO_SCALAR
  30. %type <bVal>    IfExp BoolExp BoolCond /* Expr */
  31. %type <bVal>    BetweenCond LikeCond IsNullCond InCond CompareCond AssignCond
  32. %type <bVal>    IsTrueCond IsFalseCond
  33. %type <pScalar> ScalarExp ScalarCommaList SymbolRef SimpleExp
  34. %type <pScalar> COMPARISON LT GT LE GE EQ NEQ
  35. %type <pScalar> STRING INTNUM APPROXNUM FUNCNAME LITERAL
  36. %left AND OR
  37. %nonassoc NOT
  38. %left BETWEEN LIKE IS IN COMPARISON /* LT GT LE GE EQ NEQ */
  39. %left '+' '-' CAT
  40. %left '*' '/' '%'
  41. %nonassoc UMINUS ':'
  42. %%
  43. /*
  44. /* STARTING point an IF-Expression
  45.  */
  46. IfExp:   BoolExp ';'  {gbIfResult=$1;}
  47. | IF BoolExp ';'  {gbIfResult=$2;}
  48. ;
  49. /*
  50. /* Boolean Expression-- True or False
  51.  */
  52. BoolExp:  BoolExp AND BoolExp {$$= (ISeTrue($1) && ISeTrue($3));}
  53. | BoolExp  OR BoolExp {$$= (ISeTrue($1) || ISeTrue($3));}
  54. | NOT BoolExp {$$= !ISeTrue($2);}
  55. | '(' BoolExp ')' {$$= ISeTrue($2);}
  56. | BoolCond {$$= ISeTrue($1);}
  57. ;
  58. /* 
  59. /* Predicates that return Boolean Values
  60.  */
  61. BoolCond: CompareCond {$$=$1;}
  62. | BetweenCond {$$=$1;}
  63. | LikeCond {$$=$1;}
  64. | IsNullCond {$$=$1;}
  65. | IsTrueCond {$$=$1;}
  66. | IsFalseCond {$$=$1;}
  67. | InCond {$$=$1;}
  68. | AssignCond {$$=$1;}
  69. | ScalarExp {$$=OutputScalar($1);}
  70. ;
  71. /*
  72. /* The Specific Boolean Conditions
  73.  */
  74. BetweenCond: ScalarExp NOT BETWEEN ScalarExp AND ScalarExp
  75. {$$=!BetweenCond($1,$4,$6);}
  76. | ScalarExp     BETWEEN ScalarExp AND ScalarExp
  77. {$$= BetweenCond($1,$3,$5);}
  78. ;
  79. LikeCond: ScalarExp NOT LIKE ScalarExp {$$=!LikeCond($1,$4);}
  80. | ScalarExp LIKE ScalarExp {$$= LikeCond($1,$3);}
  81. ;
  82. IsNullCond: ScalarExp IS NOT NULLX {$$=!IsNullCond($1);}
  83. | ScalarExp IS NULLX {$$= IsNullCond($1);}
  84. ;
  85. IsTrueCond: ScalarExp IS NOT TRUEX {$$=!IsScalar($1);}
  86. | ScalarExp IS TRUEX {$$= IsScalar($1);}
  87. ;
  88. IsFalseCond: ScalarExp IS NOT FALSEX {$$= IsScalar($1);}
  89. | ScalarExp IS FALSEX {$$=!IsScalar($1);}
  90. ;
  91. InCond: ScalarExp NOT IN '(' ScalarCommaList ')'
  92. {$$=!InCond($1,$5);}
  93. | ScalarExp IN '(' ScalarCommaList ')'
  94. {$$= InCond($1,$4);}
  95. ;
  96. CompareCond: ScalarExp COMPARISON ScalarExp {$$=CompareCond($2,$1,$3);}
  97. ;
  98. AssignCond: SymbolRef ASSIGN ScalarExp {$$=AssignCond($1,$3);}
  99. ;
  100. /*
  101. /* scalar expressions
  102.  */
  103. ScalarExp: ScalarExp '+' ScalarExp {$$=AddScalar($1,$3);}
  104. | ScalarExp CAT ScalarExp {$$=CatScalar($1,$3);}
  105. | ScalarExp '-' ScalarExp {$$=SubScalar($1,$3);}
  106. | ScalarExp '*' ScalarExp {$$=MultScalar($1,$3);}
  107. | ScalarExp '/' ScalarExp {$$=DivScalar($1,$3);}
  108. | ScalarExp '%' ScalarExp {$$=ModScalar($1,$3);}
  109. | '+' ScalarExp %prec UMINUS {$$=$2;}
  110. | '-' ScalarExp %prec UMINUS {$$=USubScalar($2);}
  111. | FUNCNAME '(' ScalarCommaList ')'{$$=CallFunction($1,$3);}
  112. /* All function get called
  113. /* with a LIST* of Scalar_t
  114.  */
  115. | '(' ScalarExp ')' {$$=$2;}
  116. | SimpleExp {$$=$1;}
  117. | SymbolRef {$$=$1;}
  118. ;
  119. SimpleExp: STRING {$$=$1;} /* Quoted str 'xtr' */
  120. | INTNUM {$$=$1;} /* 242 */
  121. | APPROXNUM {$$=$1;} /* 234.223 */
  122. | TO_SCALAR '(' BoolExp ')' {$$=ToScalar($3);}
  123. ;
  124. SymbolRef: ':' ScalarExp  {$$=ScalarGetSym($2,"cE");}
  125. | ':' LITERAL {$$=ScalarGetSym($2,"cL");}
  126. | ':' LITERAL '[' ScalarExp ']' {$$=ScalarGetSymARR($2,$4);}
  127. /* | LITERAL  {$$=ScalarGetSym($1,"xL");}
  128.  */
  129. ;
  130. ScalarCommaList:
  131. /* nothing */ {$$=(Scalar_t*)0;}
  132. | ScalarExp {$$=MkScalar(eListType,$1,$1->lSize);}
  133. | ScalarCommaList ',' ScalarExp
  134. {$$=AddScalarToList($1,$3);}
  135. ;
  136. %%
  137. int
  138. yylex()
  139. {
  140.     static char *fp;
  141.     static char ssBuf[ BUFSIZ ]; /* Needs to stay around */
  142. /* so I can return pointer to... */
  143.     int    i;
  144.     if(giRestart == 0) {
  145. fp = gpIfExpr;
  146. giRestart = 1;
  147.     }
  148.     /* Skip White Space
  149.      */
  150.     while( isspace( *fp ) )
  151. fp++;
  152.     /*
  153.     /* Deal with the End-Of-String
  154.      */
  155.     if( *fp == 0) {
  156. if( giRestart == -1 ) {
  157.     giRestart=0;/* Second time... */
  158.     return(0); /* That's all */
  159. }
  160. giRestart= -1; /* Sets for End above */
  161. return(';'); /* Returns Sentinal Token */
  162.     }
  163.     /* fprintf(stderr,"yylex:%sn",fp);
  164.     /* fflush(stderr);
  165.      */
  166.     /*
  167.     /* Process known single and double character character tokens
  168.      */
  169.     switch(*fp) {
  170. /*
  171. /* COMPARISON's
  172.  */
  173. case '<':
  174.     if(*(fp+1) == '='){
  175. fp+=2;
  176. yylval.pScalar = MkScalarToken(LE);
  177. return COMPARISON;
  178.     }
  179.     if(*(fp+1) == '>'){
  180. fp+=2;
  181. yylval.pScalar = MkScalarToken(NEQ);
  182. return COMPARISON;
  183.     } else {
  184. fp++;
  185. yylval.pScalar = MkScalarToken(LT);
  186. return COMPARISON;
  187.     }
  188. case '>':
  189.     if(*(fp+1) == '='){
  190. fp+=2;
  191. yylval.pScalar = MkScalarToken(GE);
  192. return COMPARISON;
  193.     } else{
  194. fp++;
  195. yylval.pScalar = MkScalarToken(GT);
  196. return COMPARISON;
  197.     }
  198. case '!':
  199.     if(*(fp+1) == '=') {
  200. fp+=2;
  201. yylval.pScalar = MkScalarToken(NEQ);
  202. return COMPARISON;
  203.     } else {
  204. fp++;
  205. yylval.pScalar = MkScalarToken('!');
  206. return COMPARISON;
  207.     }
  208. case '=':
  209.     fp++;
  210.     yylval.pScalar = MkScalarToken(EQ);
  211.     return COMPARISON;
  212. case ':':
  213.     if(*(fp+1) == '=') {
  214. yylval.pScalar = MkScalarToken(ASSIGN);
  215. fp+=2;
  216. return(ASSIGN);
  217.     } else {
  218. yylval.pScalar = MkScalarToken(':');
  219. fp++;
  220. return(':');
  221.     }
  222. case '|':
  223.     if(*(fp+1) == '|') {
  224. yylval.pScalar = MkScalarToken(CAT);
  225. fp+=2;
  226. return(CAT);
  227.     } else {
  228. yylval.pScalar = MkScalarToken('|');
  229. fp++;
  230. return('|');
  231.     }
  232.     }
  233.     /*
  234.     /* Literal strings are Single Quoted
  235.      */
  236.     if( *fp == ''' ) {
  237. for(i=0, ++fp; *fp; fp++,i++) {
  238.     if(*fp==''' && *(fp+1) != ''')
  239. break;
  240.     ssBuf[i] = *fp;
  241. }
  242. ssBuf[i]='';
  243. if(*fp) ++fp;
  244. yylval.pScalar = MkScalar(eStringType,ssBuf,1+iStrLen(ssBuf));
  245. return(STRING);
  246.     }
  247.     /*
  248.     /* Numbers start with a digit or '.'
  249.      */
  250.     if(*fp =='.' || isdigit(*fp)) {
  251. for(i=0; *fp =='.' || isdigit(*fp); fp++,i++) {
  252.     ssBuf[i] = *fp;
  253. }
  254. ssBuf[i]='';
  255. /*
  256. /* Here's where we can differentiate between INTS and
  257. /* REALS, but don't need to...
  258.  */
  259. yylval.pScalar = MkScalar(eDoubleType,ssBuf,0);
  260. return(APPROXNUM);
  261.     }
  262.     /*
  263.     /* Variables/Builtins/Reserved words start with alpha
  264.      */
  265.     if( isalpha(*fp) || *fp == '_' ) {
  266. char *pBuf;
  267. Reserved_t *pResWord;
  268. for(i=0; *fp == '_' || isalnum(*fp) ; fp++,i++)
  269.     ssBuf[i]= *fp;
  270. ssBuf[i]='';
  271. for(pResWord=gaReservedWordTable; pResWord->pName; pResWord++){
  272.     if(bStrCaseMatch(pResWord->pName,ssBuf)) {
  273. /* Got one!
  274.  */
  275. if(pResWord->iType == TOKEN)
  276.     return(pResWord->iToken);
  277. yylval.pScalar = MkScalar(eStringType,ssBuf,1+iStrLen(ssBuf));
  278. return(pResWord->iToken);
  279.     }
  280. }
  281. /*
  282. /* Look up variable name
  283.  */
  284. yylval.pScalar = MkScalar(eStringType,ssBuf,1+iStrLen(ssBuf));
  285. return(LITERAL);
  286.     }
  287.     return(*fp++);
  288. }
  289. void
  290. yyerror(char *s)
  291. {
  292.     giRestart=0;
  293.     /*
  294.     /* fprintf(stderr,"yyerror:%sn",s);
  295.      */
  296.     MsgPush("ifparse error:%sn",s);
  297.     return;
  298. }
  299. eBoolean_t 
  300. ParseIf(char *pExpr, eBoolean_t *pbResult)
  301. {
  302.     giRestart=0; /* Restart at beginning of string */
  303.     gbIfResult=eFalse; /* Init Result to FALSE, feel lucky punk? */
  304.     gpIfExpr=pExpr; /* Set the Global Expression for yylex(); */
  305.     if(yyparse()) { /* Parse it! */
  306. MsgPush("Parser:Failed on "%s"",pExpr);
  307. *pbResult = gbIfResult;
  308. return(eFalse);
  309.     }
  310.     *pbResult = gbIfResult;
  311.     return(eTrue);
  312. }
  313. #ifdef MAIN_TEST
  314. int
  315. main(int argc, char **argv)
  316. {
  317.     if( ISeTrue(ParseIf(argv[1]) ) ) {
  318. fprintf(stderr,"Its TRUE!n");
  319.     } else {
  320. fprintf(stderr,"FALSEn");
  321.     }
  322.     exit(0);
  323. }
  324. int strcasecmp(char *s, char *t){ return iStrCaseCmp(s,t); }
  325. #endif