📄 ezexpryacc.pas
字号:
// Template for ExprParser
// Expression parser (c) 2003 EzGis
unit EzExprYacc;
{$I ez_flag.pas}
{$R ezexpryacc.res}
interface
uses
SysUtils, Classes, Dialogs, Windows, EzYaccLib, EzBaseExpr,
EzBase, EzSystem, EzExpressions, EzLib, EzBaseGis;
type
TIdentifierFunctionEvent = procedure( Sender: TObject;
const Group, Identifier: String;
ParameterList: TParameterList;
var Expression: TExpression ) of object;
TExprParser = class(TCustomParser)
private
{ belong to }
FMainExpr: TEzMainExpr;
{ the list of expression as the expression is parsed }
FExprList: TList;
{ for local use }
FTempParams: TParameterList;
FGroupIdent: string;
FIdentifier: string;
FGroupIdentList: TStringList;
FIdentifierList: TStringList;
{ is not this a simple expression ? like TABLE.FIELD
this is used for detecting if giving the same data type to the
result set as the original field }
FIsComplex: Boolean;
{ used to obtain a pair of operators }
Op1, Op2: TExpression;
{ a stacked list of params referencing to FExprList }
FStackedParamCount: TList;
{ the number of parameters for the last function }
FParamCount: Integer;
{ for the case..when..else..end }
FWhenParamList: TParameterList;
FThenParamList: TParameterList;
FElseExpr: TExpression;
{ used when parsing syntax like
VECTOR( [(0,0),(10,10),(20,20),(0,0)] ) }
FVector: TEzVector;
{ used in unknown identifiers }
IDF: TExpression;
FOnIdentifierFunction: TIdentifierFunctionEvent;
{ for saving configuration}
FSavedNegCurrFormat: Byte;
FSavedThousandSeparator: Char;
FSavedDecimalSeparator: Char;
FNumRecords: Integer;
FBufferWidth: Double;
FVectorType: TEzVectorType;
FOrderBy: TStrings;
FDescending: Boolean;
FClosestMax: Integer;
function AddExpression(Expression: TExpression): TExpression;
function GetParamList: TParameterList;
function ForceParamList(Count: Integer): TParameterList;
procedure GetTwoOperators;
procedure GetOneOperator;
procedure AddParam;
function GetString( const s: string ): string;
public
constructor Create(MainExpr: TEzMainExpr);
destructor Destroy; override;
function yyparse : integer; override;
function GetExpression: TExpression;
property IsComplex: Boolean read FIsComplex write FIsComplex;
property OnIdentifierFunction: TIdentifierFunctionEvent read FOnIdentifierFunction write FOnIdentifierFunction;
property Vector: TEzVector read FVector;
property OrderBy: TStrings read FOrderBy;
property ClosestMax: Integer read FClosestMax;
end;
const _IDENTIFIER = 257;
const _UINTEGER = 258;
const _SINTEGER = 259;
const _NUMERIC = 260;
const _STRING = 261;
const _COMA = 262;
const _LPAREN = 263;
const _RPAREN = 264;
const _LSQUARE = 265;
const _RSQUARE = 266;
const _PERIOD = 267;
const _SEMICOLON = 268;
const _COMMENT = 269;
const _BLANK = 270;
const _TAB = 271;
const _NEWLINE = 272;
const RW_OR = 273;
const RW_XOR = 274;
const RW_AND = 275;
const _EQ = 276;
const _NEQ = 277;
const _GT = 278;
const _LT = 279;
const _GE = 280;
const _LE = 281;
const RW_BETWEEN = 282;
const RW_IN = 283;
const RW_LIKE = 284;
const _PLUS = 285;
const _SUB = 286;
const _DIV = 287;
const RW_DIV = 288;
const _MULT = 289;
const RW_MOD = 290;
const RW_SHL = 291;
const RW_SHR = 292;
const UMINUS = 293;
const _EXP = 294;
const RW_NOT = 295;
const _ILLEGAL = 296;
const RW_TRUE = 297;
const RW_FALSE = 298;
const RW_STRING = 299;
const RW_FLOAT = 300;
const RW_INTEGER = 301;
const RW_BOOLEAN = 302;
const RW_CASE = 303;
const RW_WHEN = 304;
const RW_THEN = 305;
const RW_ELSE = 306;
const RW_END = 307;
const RW_IF = 308;
const RW_CAST = 309;
const RW_AS = 310;
const RW_ESCAPE = 311;
const RW_WITHIN = 312;
const RW_ENTIRELY = 313;
const RW_CONTAINS = 314;
const RW_ENTIRE = 315;
const RW_INTERSECTS = 316;
const RW_EXTENT = 317;
const RW_OVERLAPS = 318;
const RW_SHARE = 319;
const RW_COMMON = 320;
const RW_POINT = 321;
const RW_LINE = 322;
const RW_CROSS = 323;
const RW_EDGE = 324;
const RW_TOUCH = 325;
const RW_CENTROID = 326;
const RW_IDENTICAL = 327;
const RW_VECTOR = 328;
const RW_ALL = 329;
const RW_RECORDS = 330;
const RW_ENT = 331;
const RW_SCOPE = 332;
const RW_POLYLINE = 333;
const RW_POLYGON = 334;
const RW_BUFFER = 335;
const RW_WIDTH = 336;
const RW_ORDER = 337;
const RW_BY = 338;
const RW_DESC = 339;
const RW_DESCENDING = 340;
type YYSType = record
yystring : string
end(*YYSType*);
// global definitions:
var yylval : YYSType;
implementation
(*----------------------------------------------------------------------------*)
constructor TExprParser.Create(MainExpr: TEzMainExpr);
begin
inherited Create;
FMainExpr:= MainExpr; { belongs to }
FExprList:= TList.Create;
FStackedParamCount:= TList.Create;
FGroupIdentList:= TStringList.create;
FIdentifierList:= TStringList.create;
FVector:= TEzVector.Create(10);
FOrderBy:= TStringList.Create;
{ save configuration }
FSavedNegCurrFormat:= NegCurrFormat;
FSavedThousandSeparator:= ThousandSeparator;
FSavedDecimalSeparator:= DecimalSeparator;
NegCurrFormat:= 1;
ThousandSeparator:= ',';
DecimalSeparator:= '.';
end;
destructor TExprParser.Destroy;
var
I: Integer;
begin
for I:= 0 to FExprList.Count-1 do
TObject(FExprList[I]).Free;
FExprList.Free;
if FWhenParamList<>nil then
FWhenParamList.Free;
if FThenParamList<>nil then
FThenParamList.Free;
if FElseExpr<>nil then
FElseExpr.Free;
FStackedParamCount.Free;
FGroupIdentList.free;
FIdentifierList.free;
FVector.Free;
FOrderBy.Free;
{ restore configuration }
NegCurrFormat:= FSavedNegCurrFormat;
ThousandSeparator:= FSavedThousandSeparator;
DecimalSeparator:= FSavedDecimalSeparator;
inherited Destroy;
end;
function TExprParser.GetString( const s: string ): string;
begin
result:= copy( s, 2, length(s) - 2 );
end;
{ this function returns the final expression obtained }
function TExprParser.GetExpression: TExpression;
begin
Result:= nil;
if FExprList.Count <> 1 then Exit;
Result := TExpression( FExprList[0] );
FExprList.Delete( 0 );
end;
function TExprParser.GetParamList: TParameterList;
var
I: Integer;
NumParams: Integer;
begin
Result:= nil;
if FStackedParamCount.Count=0 then
NumParams:= 0
else
begin
NumParams:= Longint(FStackedParamCount[FStackedParamCount.Count-1]);
FStackedParamCount.Delete(FStackedParamCount.Count-1);
end;
if (FExprList.Count=0) or (NumParams=0) or (NumParams>FExprList.Count) then Exit;
Result:= TParameterList.Create;
for I:= 0 to NumParams - 1 do
Result.Add(FExprList[FExprList.Count - NumParams + I]);
while NumParams > 0 do
begin
FExprList.Delete(FExprList.Count-1);
Dec(NumParams);
end;
end;
function TExprParser.ForceParamList(Count: Integer): TParameterList;
var
I: Integer;
NumParams: Integer;
begin
Result:= nil;
NumParams:= Count;
if (FExprList.Count=0) or (NumParams=0) or (NumParams>FExprList.Count) then Exit;
Result:= TParameterList.Create;
for I:= 0 to NumParams - 1 do
Result.Add(FExprList[FExprList.Count - NumParams + I]);
while NumParams > 0 do
begin
FExprList.Delete(FExprList.Count-1);
Dec(NumParams);
end;
end;
procedure TExprParser.GetTwoOperators;
begin
Op1:= TExpression( FExprList[FExprList.Count - 2] );
Op2:= TExpression( FExprList[FExprList.Count - 1] );
FExprList.Delete( FExprList.Count - 1 );
FExprList.Delete( FExprList.Count - 1 );
end;
procedure TExprParser.GetOneOperator;
begin
Op1:= TExpression( FExprList[FExprList.Count - 1] );
FExprList.Delete( FExprList.Count - 1 );
end;
procedure TExprParser.AddParam;
begin
FParamCount:= Longint(FStackedParamCount[FStackedParamCount.Count-1]);
Inc(FParamCount);
FStackedParamCount[FStackedParamCount.Count-1]:= Pointer(FParamCount);
end;
function TExprParser.AddExpression( Expression: TExpression ): TExpression;
begin
FExprList.Add( Expression );
FIsComplex:= True;
Result:= Expression;
end;
// function yylex : Integer; forward; // addition 1
function TExprParser.yyparse : Integer; // addition 2
var yystate, yysp, yyn : SmallInt;
yys : array [1..yymaxdepth] of SmallInt;
yyv : array [1..yymaxdepth] of YYSType;
yyval : YYSType;
procedure yyaction ( yyruleno : Integer );
(* local definitions: *)
var
IntVal, Code: Integer;
begin
(* actions: *)
case yyruleno of
1 : begin
yyval := yyv[yysp-1];
end;
2 : begin
yyval := yyv[yysp-0];
end;
3 : begin
yyval := yyv[yysp-0];
end;
4 : begin
AddExpression( TEntExpr.Create(nil, FMainExpr.Gis, FMainExpr.DefaultLayer) );
end;
5 : begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -