📄 qexpryacc.y
字号:
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 + -