⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qexpryacc.y

📁 TxQuery is an SQL engine implemented in a TDataSet descendant component, that can parse SQL syntax,
💻 Y
📖 第 1 页 / 共 4 页
字号:
  FStackedParamCount[FStackedParamCount.Count-1]:= Pointer(FParamCount);
end;

function TExprParser.AddExpression(Expression: TExpression): TExpression;
begin
  FExprList.Add(Expression);
  FIsComplex:= True;
  Result:= Expression;
end;

Function TExprParser.GetExplicitParam( const ParamName: string ): string;
var
  pf: TParamsAsFieldsItem;
  Param: TParam;
begin
  Result:= '';
  if fAnalizer = Nil then Exit;
  // First a search on the ParamsAsFields property
  if TSqlAnalizer(fAnalizer).XQuery.ParamsAsFields.Count > 0 then
  begin
    pf := TSqlAnalizer(fAnalizer).XQuery.ParamsAsFields.ParamByName( ParamName );
    if pf <> Nil then
    begin
      Result:= TSqlAnalizer(fAnalizer).QualifiedField( '\f"' + pf.Value + '"', True );
      Exit;
    end;
  end;
  // if not found then replace with default params
  Param:= TSqlAnalizer(fAnalizer).xQuery.ParamByName( ParamName );
  if Param = Nil then
    raise ExQueryError(Format(SParameterNotFound,[ParamName]));
  // return param value
  Result:= Param.AsString;
  FExprList.Add(TExplicitParamExpr.Create( TSqlAnalizer(fAnalizer), Param ));
end;

%}

%start basic_expr

%token _IDENTIFIER
%token _UINTEGER
%token _SINTEGER
%token _NUMERIC
%token _STRING

%token _COMA
%token _LPAREN
%token _RPAREN
%token _PERIOD
%token _COLON

%left  RW_OR RW_XOR RW_AND
%left  _EQ _NEQ _GT _LT _GE _LE RW_BETWEEN RW_IN RW_LIKE
%left  _PLUS _SUB
%left  _DIV RW_DIV _MULT RW_MOD RW_SHL RW_SHR
%right UMINUS       /* Negation--unary minus */
%right _EXP         /* exponentiation */
%left  RW_NOT
%token _ILLEGAL


/* other reserved words and tokens */
%token  _COMMENT
        _BLANK
        _TAB
        _NEWLINE
        RW_TRUE
        RW_FALSE
        RW_STRING
        RW_FLOAT
        RW_INTEGER
        RW_BOOLEAN
        RW_IN
        RW_CASE
        RW_WHEN
        RW_THEN
        RW_ELSE
        RW_END
        RW_IF
        RW_CAST
        RW_AS
        RW_ESCAPE

%type <string>

%%

basic_expr : expr_constant
           | define_identifier parameter_list
             { FGroupIdent:= FGroupIdentList[FGroupIdentList.Count-1];
               FGroupIdentList.Delete(FGroupIdentList.Count-1);
               FIdentifier:= FIdentifierList[FIdentifierList.Count-1];
               FIdentifierList.Delete(FIdentifierList.Count-1);
               FTempParams:= GetParamList;

               IDF:=nil;
               IDFunc(Self, FGroupIdent, FIdentifier, FTempParams, IDF);
               if IDF <> nil then
               begin
                 if Length(FGroupIdent)=0 then
                   AddExpression(IDF)
                 else
                 begin
                   FExprList.Add(IDF);
                   if FTempParams=nil then
                   begin
                     if FIdReferences.IndexOf( FGroupIdent + '.' + FIdentifier ) < 0 then
                       FIdReferences.Add(FGroupIdent + '.' + FIdentifier);
                   end;
                 end;
               end else
               begin
                 if CompareText(FIdentifier,'LTRIM')=0 then
                   IDF:= AddExpression(TStringExpression.Create(FTempParams, sfLTrim))
                 else if CompareText(FIdentifier,'NULL')=0 then
                   IDF:= AddExpression(TNullValueExpr.Create(FTempParams))
                 else if CompareText(FIdentifier,'RTRIM')=0 then
                   IDF:= AddExpression(TStringExpression.Create(FTempParams, sfRTrim))
                 else if CompareText(FIdentifier,'TRIM')=0 then
                   IDF:= AddExpression(TStringExpression.Create(FTempParams, sfTrim))
                 else if CompareText(FIdentifier,'TRUNC')=0 then
                   IDF:= AddExpression(TMathExpression.Create(FTempParams, mfTrunc))
                 else if CompareText(FIdentifier,'ROUND')=0 then
                   IDF:= AddExpression(TMathExpression.Create(FTempParams, mfRound))
                 else if CompareText(FIdentifier,'ABS')=0 then
                   IDF:= AddExpression(TMathExpression.Create(FTempParams, mfAbs))
                 else if CompareText(FIdentifier,'ARCTAN')=0 then
                   IDF:= AddExpression(TMathExpression.Create(FTempParams, mfArcTan))
                 else if CompareText(FIdentifier,'COS')=0 then
                   IDF:= AddExpression(TMathExpression.Create(FTempParams, mfCos))
                 else if CompareText(FIdentifier,'SIN')=0 then
                   IDF:= AddExpression(TMathExpression.Create(FTempParams, mfSin))
                 else if CompareText(FIdentifier,'EXP')=0 then
                   IDF:= AddExpression(TMathExpression.Create(FTempParams, mfExp))
                 else if CompareText(FIdentifier,'FRAC')=0 then
                   IDF:= AddExpression(TMathExpression.Create(FTempParams, mfFrac))
                 else if CompareText(FIdentifier,'INT')=0 then
                   IDF:= AddExpression(TMathExpression.Create(FTempParams, mfInt))
                 else if CompareText(FIdentifier,'LN')=0 then
                   IDF:= AddExpression(TMathExpression.Create(FTempParams, mfLn))
                 else if CompareText(FIdentifier,'PI')=0 then
                   IDF:= AddExpression(TMathExpression.Create(FTempParams, mfPi))
                 else if CompareText(FIdentifier,'SQR')=0 then
                   IDF:= AddExpression(TMathExpression.Create(FTempParams, mfSqr))
                 else if CompareText(FIdentifier,'SQRT')=0 then
                   IDF:= AddExpression(TMathExpression.Create(FTempParams, mfSqrt))
                 else if CompareText(FIdentifier,'POWER')=0 then
                   IDF:= AddExpression(TMathExpression.Create(FTempParams, mfPower))
                 else if CompareText(FIdentifier,'UPPER')=0 then
                   IDF:= AddExpression(TStringExpression.Create(FTempParams, sfUpper))
                 else if CompareText(FIdentifier,'LOWER')=0 then
                   IDF:= AddExpression(TStringExpression.Create(FTempParams, sfLower))
                 else if CompareText(FIdentifier,'COPY')=0 then
                   IDF:= AddExpression(TStringExpression.Create(FTempParams, sfCopy))
                 else if CompareText(FIdentifier,'SUBSTRING')=0 then
                   IDF:= AddExpression(TStringExpression.Create(FTempParams, sfCopy))
                 else if CompareText(FIdentifier,'POS')=0 then
                   IDF:= AddExpression(TStringExpression.Create(FTempParams, sfPos))
                 else if CompareText(FIdentifier,'CHARINDEX')=0 then
                   IDF:= AddExpression(TStringExpression.Create(FTempParams, sfPos))
                 else if CompareText(FIdentifier,'LENGTH')=0 then
                   IDF:= AddExpression(TStringExpression.Create(FTempParams, sfLength))
                 else if CompareText(FIdentifier,'LEFT')=0 then
                   IDF:= AddExpression(TLeftExpr.Create(FTempParams))
                 else if CompareText(FIdentifier,'RIGHT')=0 then
                   IDF:= AddExpression(TRightExpr.Create(FTempParams))
                 else if CompareText(FIdentifier,'YEAR')=0 then
                   IDF:= AddExpression(TDecodeDateTimeExpr.Create(FTempParams, dkYear))
                 else if CompareText(FIdentifier,'MONTH')=0 then
                   IDF:= AddExpression(TDecodeDateTimeExpr.Create(FTempParams, dkMonth))
                 else if CompareText(FIdentifier,'DAY')=0 then
                   IDF:= AddExpression(TDecodeDateTimeExpr.Create(FTempParams, dkDay))
                 else if CompareText(FIdentifier,'HOUR')=0 then
                   IDF:= AddExpression(TDecodeDateTimeExpr.Create(FTempParams, dkHour))
                 else if CompareText(FIdentifier,'MIN')=0 then
                   IDF:= AddExpression(TDecodeDateTimeExpr.Create(FTempParams, dkMin))
                 else if CompareText(FIdentifier,'SEC')=0 then
                   IDF:= AddExpression(TDecodeDateTimeExpr.Create(FTempParams, dkSec))
                 else if CompareText(FIdentifier,'MSEC')=0 then
                   IDF:= AddExpression(TDecodeDateTimeExpr.Create(FTempParams, dkMSec))
                 else if CompareText(FIdentifier,'FORMATDATETIME')=0 then
                   IDF:= AddExpression(TFormatDateTimeExpr.Create(FTempParams))
                 else if CompareText(FIdentifier,'FORMATFLOAT')=0 then
                   IDF:= AddExpression(TFormatFloatExpr.Create(FTempParams))
                 else if CompareText(FIdentifier,'FORMAT')=0 then
                   IDF:= AddExpression(TFormatExpr.Create(FTempParams))
                 else if CompareText(FIdentifier,'DECODE')=0 then
                   IDF:= AddExpression(TDecodeExpr.Create(FTempParams))
                 else if CompareText(FIdentifier,'MINOF')=0 then
                   IDF:= AddExpression(TMinMaxOfExpr.Create(FTempParams, True))
                 else if CompareText(FIdentifier,'MAXOF')=0 then
                   IDF:= AddExpression(TMinMaxOfExpr.Create(FTempParams, False))
                 else if CompareText(FIdentifier,'SQLLIKE')=0 then
                   IDF:= AddExpression(TSQLLikeExpr.Create(FTempParams, False))
                 else if CompareText(FIdentifier,'SQLNOTLIKE')=0 then
                   IDF:= AddExpression(TSQLLikeExpr.Create(FTempParams, True))
                 else if CompareText(FIdentifier,'ASCII')=0 then
                   IDF:= AddExpression(TASCIIExpr.Create(FTempParams));
               end;
               if IDF= nil then
               begin
                 FTempParams.Free;
                 yyerror(Format('Unknown Identifier %s', [$<string>1]));
                 yyabort;
                 Exit;
               end;
             }
           | RW_CAST _LPAREN basic_expr RW_AS RW_STRING _RPAREN
             { AddExpression(TTypeCast.Create(ForceParamList(1), ttString)); }
           | RW_FLOAT parameter_list
             { AddExpression(TTypeCast.Create(GetParamList, ttFloat)); }
           | RW_CAST _LPAREN basic_expr RW_AS RW_FLOAT _RPAREN
             { AddExpression(TTypeCast.Create(ForceParamList(1), ttFloat)); }
           | RW_INTEGER parameter_list
             { AddExpression(TTypeCast.Create(GetParamList, ttInteger)); }
           | RW_CAST _LPAREN basic_expr RW_AS RW_INTEGER _RPAREN
             { AddExpression(TTypeCast.Create(ForceParamList(1), ttInteger)); }
           | RW_BOOLEAN parameter_list
             { AddExpression(TTypeCast.Create(GetParamList, ttBoolean)); }
           | RW_CAST _LPAREN basic_expr RW_AS RW_BOOLEAN _RPAREN
             { AddExpression(TTypeCast.Create(ForceParamList(1), ttBoolean)); }
           | RW_IF parameter_list
             { AddExpression(TConditional.Create(GetParamList)); }
           | case_clause
             { AddExpression(TCaseWhenElseExpr.Create(FWhenParamList, FThenParamList, FElseExpr));
               FWhenParamList:= nil;
               FThenParamList:= nil;
               FElseExpr:= nil;
             }
           | basic_expr RW_BETWEEN expr_constant RW_AND expr_constant
             { AddExpression( TBetweenExpr.Create(ForceParamList(3), FALSE) ); }
           | basic_expr RW_NOT RW_BETWEEN expr_constant RW_AND expr_constant
             { AddExpression( TBetweenExpr.Create(ForceParamList(3), TRUE) ); }
           | basic_expr RW_IN parameter_list
             { AddExpression( TSQLInPredicateExpr.Create(ForceParamList(FParamCount + 1), FALSE) ); }
           | basic_expr RW_NOT RW_IN parameter_list
             { AddExpression( TSQLInPredicateExpr.Create(ForceParamList(FParamCount + 1), TRUE) ); }
           | basic_expr RW_LIKE expr_constant escape_character
             { AddExpression(TSQLLikeExpr.Create(ForceParamList(3), FALSE)); }
           | basic_expr RW_NOT RW_LIKE expr_constant escape_character
             { AddExpression(TSQLLikeExpr.Create(ForceParamList(3), TRUE)); }
           | _SUB basic_expr %prec UMINUS
             { GetOneOperator;
               AddExpression(TUnaryOp.Create(opMinus, Op1));
               FIsComplex:= True;}
           | _PLUS basic_expr %prec UMINUS
             { GetOneOperator;
               AddExpression(TUnaryOp.Create(opPlus, Op1));
               FIsComplex:= True;}
           | RW_NOT basic_expr
             { GetOneOperator;
               AddExpression(TUnaryOp.Create(opNot, Op1));
               FIsComplex:= True;}
           | basic_expr _PLUS basic_expr
             { GetTwoOperators;
               AddExpression(TBinaryOp.Create(opPlus, Op1, Op2));
               FIsComplex:= True;}
           | basic_expr _SUB basic_expr
             { GetTwoOperators;
               AddExpression(TBinaryOp.Create(opMinus, Op1, Op2));
               FIsComplex:= True;}
           | basic_expr _MULT basic_expr
             { GetTwoOperators;
               AddExpression(TBinaryOp.Create(opMult, Op1, Op2));
               FIsComplex:= True;}
           | basic_expr _DIV basic_expr
             { GetTwoOperators;
               AddExpression(TBinaryOp.Create(opDivide, Op1, Op2));
               FIsComplex:= True;}
           | basic_expr RW_DIV basic_expr
             { GetTwoOperators;
               AddExpression(TBinaryOp.Create(opDiv, Op1, Op2));
               FIsComplex:= True;}
           | basic_expr _EXP basic_expr
             { GetTwoOperators;
               AddExpression(TBinaryOp.Create(opExp, Op1, Op2));
               FIsComplex:= True;}
           | basic_expr RW_MOD basic_expr
             { GetTwoOperators;
               AddExpression(TBinaryOp.Create(opMod, Op1, Op2));
               FIsComplex:= True;}
           | basic_expr RW_SHL basic_expr
             { GetTwoOperators;
               AddExpression(TBinaryOp.Create(opShl, Op1, Op2));
               FIsComplex:= True;}
           | basic_expr RW_SHR basic_expr
             { GetTwoOperators;
               AddExpression(TBinaryOp.Create(opShr, Op1, Op2));
               FIsComplex:= True;}
           | basic_expr _GE basic_expr
             { GetTwoOperators;
               AddExpression(TRelationalOp.Create(opGTE, Op1, Op2));
               FIsComplex:= True;}
           | basic_expr _LE basic_expr
             { GetTwoOperators;
               AddExpression(TRelationalOp.Create(opLTE, Op1, Op2));
               FIsComplex:= True;}
           | basic_expr _GT basic_expr
             { GetTwoOperators;
               AddExpression(TRelationalOp.Create(opGT, Op1, Op2));
               FIsComplex:= True;}
           | basic_expr _LT basic_expr
             { GetTwoOperators;
               AddExpression(TRelationalOp.Create(opLT, Op1, Op2));
               FIsComplex:= True;}
           | basic_expr _EQ basic_expr
             { GetTwoOperators;
               AddExpression(TRelationalOp.Create(opEQ, Op1, Op2));
               FIsComplex:= True;}
           | basic_expr _NEQ basic_expr
             { GetTwoOperators;
               AddExpression(TRelationalOp.Create(opNEQ, Op1, Op2));
               FIsComplex:= True;}
           | basic_expr RW_AND basic_expr
             { GetTwoOperators;
               AddExpression(TBinaryOp.Create(opAnd, Op1, Op2));
               FIsComplex:= True;}
           | basic_expr RW_OR basic_expr
             { GetTwoOperators;
               AddExpression(TBinaryOp.Create(opOr, Op1, Op2));
               FIsComplex:= True;}
           | basic_expr RW_XOR basic_expr
             { GetTwoOperators;
               AddExpression(TBinaryOp.Create(opXor, Op1, Op2));
               FIsComplex:= True;}
           | _LPAREN basic_expr _RPAREN
             { FIsComplex:= True; }
           ;

parameter_list : /* empty */
                 { FStackedParamCount.Add(Pointer(0)); }
               | start_list _RPAREN
               | start_list list_param _RPAREN
               ;

start_list : _LPAREN
             { FStackedParamCount.Add(Pointer(0)); }
           ;

list_param : basic_expr
             { AddParam; }
           | list_param _COMA basic_expr
             { AddParam; }
           ;

/* CASE...WHEN...THEN...ELSE...END clause */
case_clause : RW_CASE when_list else_clause RW_END
            ;

when_list : when_clause
          | when_list when_clause
          ;

when_clause : RW_WHEN basic_expr RW_THEN basic_expr
              { if FWhenParamList=nil then
                  FWhenParamList:= TParameterList.Create;
                if FThenParamList=nil then
                  FThenParamList:= TParameterList.Create;
                FWhenParamList.Add(FExprList[FExprList.Count-2]);
                FThenParamList.Add(FExprList[FExprList.Count-1]);
                FExprList.Delete(FExprList.Count-1);
                FExprList.Delete(FExprList.Count-1);
              }
            ;

else_clause : /* empty */
            | RW_ELSE basic_expr
              { FElseExpr:= TExpression(FExprList[FExprList.Count-1]);
                FExprList.Delete(FExprList.Count-1);
              }
            ;

define_identifier : _IDENTIFIER
                    { FGroupIdentList.Add('');
                      FIdentifierList.Add(UpperCase($<string>1));
                    }
                  | _IDENTIFIER _PERIOD _IDENTIFIER
                    { FGroupIdentList.Add(UpperCase($<string>1));
                      FIdentifierList.Add(UpperCase($<string>3));
                    }
                  ;

expr_constant : _UINTEGER
                { Val($<string>1, IntVal, Code);
                  if Code=0 then
                    FExprList.Add(TIntegerLiteral.Create(StrToInt($<string>1)))
                  else
                    FExprList.Add(TFloatLiteral.Create(StrToFloat($<string>1)));
                }
              | _SINTEGER
                { Val($<string>1, IntVal, Code);
                  if Code=0 then
                    FExprList.Add(TIntegerLiteral.Create(StrToInt($<string>1)))
                  else
                    FExprList.Add(TFloatLiteral.Create(StrToFloat($<string>1)));
                }
              | _NUMERIC   { FExprList.Add(TFloatLiteral.Create(StrToFloat($<string>1))); }
              | _STRING    { FExprList.Add(TStringLiteral.Create( GetString( $<string>1 ) )); }
              | RW_TRUE    { FExprList.Add(TBooleanLiteral.Create(True)); }
              | RW_FALSE   { FExprList.Add(TBooleanLiteral.Create(False)); }
              | _COLON _IDENTIFIER
                {$<string>$ := GetExplicitParam( $<string>2 );}
              ;

escape_character : /* empty */
                   { FExprList.Add(TStringLiteral.Create('')); }
                 | RW_ESCAPE _STRING
                   { FExprList.Add(TStringLiteral.Create(GetString( $<string>2 ))); }
                 ;

%%

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -