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

📄 ezexprlex.l

📁 很管用的GIS控件
💻 L
字号:

%{

{**************************************************}
{   Lexical analizer for EzGis Expression Parser   }
{**************************************************}

unit EzExprLex;

{$I ez_flag.pas}
interface

uses
  SysUtils, EzLexLib, EzExprYacc;

type
  TExprLexer = Class(TCustomLexer)
  public
    // utility functions
    function IsKeyword(const id : String; var token : integer) : boolean;
    // Lexer main functions
    function yylex : Integer; override;
    procedure yyaction( yyruleno : integer);
    procedure commenteof;
  end;

//===============================================
// reserved words definition
//===============================================

  TRWord = record
     rword: string[14];
     token: smallint;
  end;

  const
    rwords : array [1..55] of TRword = (
      (rword: 'AND';            token: RW_AND),
      (rword: 'OR';             token: RW_OR),
      (rword: 'XOR';            token: RW_XOR),
      (rword: 'NOT';            token: RW_NOT),
      (rword: 'MOD';            token: RW_MOD),
      (rword: 'TRUE';           token: RW_TRUE),
      (rword: 'FALSE';          token: RW_FALSE),
      (rword: 'LIKE';           token: RW_LIKE),
      (rword: 'STRING';         token: RW_STRING),
      (rword: 'FLOAT';          token: RW_FLOAT),
      (rword: 'INTEGER';        token: RW_INTEGER),
      (rword: 'BOOLEAN';        token: RW_BOOLEAN),
      (rword: 'SHL';            token: RW_SHL),
      (rword: 'SHR';            token: RW_SHR),
      (rword: 'IN';             token: RW_IN),
      (rword: 'BETWEEN';        token: RW_BETWEEN),
      (rword: 'DIV';            token: RW_DIV),
      (rword: 'CASE';           token: RW_CASE),
      (rword: 'WHEN';           token: RW_WHEN),
      (rword: 'THEN';           token: RW_THEN),
      (rword: 'ELSE';           token: RW_ELSE),
      (rword: 'IF';             token: RW_IF),
      (rword: 'CAST';           token: RW_CAST),
      (rword: 'ESCAPE';         token: RW_ESCAPE),
      (rword: 'AS';             token: RW_AS),
      (rword: 'END';            token: RW_END),
      (rword: 'WITHIN';         token: RW_WITHIN),
      (rword: 'ENTIRELY';       token: RW_ENTIRELY),
      (rword: 'CONTAINS';       token: RW_CONTAINS),
      (rword: 'ENTIRE';         token: RW_ENTIRE),
      (rword: 'INTERSECTS';     token: RW_INTERSECTS),
      (rword: 'EXTENT';         token: RW_EXTENT),
      (rword: 'OVERLAPS';       token: RW_OVERLAPS),
      (rword: 'SHARE';          token: RW_SHARE),
      (rword: 'COMMON';         token: RW_COMMON),
      (rword: 'POINT';          token: RW_POINT),
      (rword: 'LINE';           token: RW_LINE),
      (rword: 'CROSS';          token: RW_CROSS),
      (rword: 'EDGE';           token: RW_EDGE),
      (rword: 'TOUCH';          token: RW_TOUCH),
      (rword: 'CENTROID';       token: RW_CENTROID),
      (rword: 'IDENTICAL';      token: RW_IDENTICAL),
      (rword: 'VECTOR';         token: RW_VECTOR),
      (rword: 'ALL';            token: RW_ALL),
      (rword: 'RECORDS';        token: RW_RECORDS),
      (rword: 'SCOPE';          token: RW_SCOPE),
      (rword: 'ENT';            token: RW_ENT),
      (rword: 'POLYLINE';       token: RW_POLYLINE),
      (rword: 'POLYGON';        token: RW_POLYGON),
      (rword: 'BUFFER';         token: RW_BUFFER),
      (rword: 'WIDTH';          token: RW_WIDTH),
      (rword: 'ORDER';          token: RW_ORDER),
      (rword: 'BY';             token: RW_BY),
      (rword: 'DESC';           token: RW_DESC),
      (rword: 'DESCENDING';     token: RW_DESCENDING)
    );

implementation

resourcestring
  SDefaultDateFormat = 'm/d/yyyy';

function TExprLexer.IsKeyword(const id : string; var token : integer) : boolean;
(* returns corresponding token number in token *)

var
  k : integer;
begin
  Result:= false;
  for k:= Low(rwords) to High(rwords) do
     if AnsiCompareText(id, rwords[k].rword)=0 then
     begin
        Result:= True;
        token := rwords[k].token;
        Exit;
     end;
end;

procedure TExprLexer.commenteof;
begin
  writeln(yyErrorfile, 'unexpected EOF inside comment at line ' +intToStr( yylineno));
end;

%}

DIGIT     [0-9]
LOWER     [a-z]
UPPER     [A-Z]
EXTENDED  [\200-\377]
LETTER    ({UPPER}|{LOWER}|{EXTENDED})

UINT      {DIGIT}+
SINT      [+-]{DIGIT}+
HEXA      [$]({DIGIT}|[A-Fa-f])+
ENL       ([+-])?({UINT}"."{UINT})|({UINT}".")|("."{UINT})
ANL       {ENL}[Ee]{SINT}

%%

   var
      c : Char;
      token, code, value: Integer;
      SaveDate: String;

{LETTER}("_"|{LETTER}|{DIGIT})*
  if IsKeyword(yylval.yystring, token) then
    returni(token)
  else
    returni(_IDENTIFIER);
\[{LETTER}[^\[\]]*\]
  begin
    // extended identifier for using in fields with same name as reserved word
    yylval.yystring := Copy(yylval.yystring, 2, Length(yylval.yystring) - 2);
    returni( _IDENTIFIER );
  end;

({ENL})|({ANL})      returni( _NUMERIC );

{UINT}               returni( _UINTEGER );

{SINT}               returni( _SINTEGER );

{HEXA}
  begin
    Val(yylval.yystring,value,code);
    if code=0 then
    begin
      yylval.yystring:= IntToStr(value);
      returni(_NUMERIC);
    end else
      returni(_ILLEGAL);
  end;

\'[^\']*\'
  begin
    c := get_char;
    if c = #39 then
      yymore
    else
    begin
      unget_char(c);
      returni( _STRING );
    end;
  end;
\"[^\"]*\"
  begin
    c := get_char;
    if c = #34 then
      yymore
    else
    begin
      unget_char(c);
      returni( _STRING );
    end;
  end;
\#[^\#]*\#
  if yyTextLen >= 10 then
  begin
    { section to handle dates in the format m/d/yyyy }
    SaveDate := ShortDateFormat;
    ShortDateFormat := SDefaultDateFormat;
    yylval.yystring := FloatToStr(StrToDate(Copy(yylval.yystring, 2, Length(yylval.yystring) - 2)));
    ShortDateFormat := SaveDate;
    returni(_NUMERIC);
  end;
","  returni( _COMA );
"("  returni( _LPAREN );
")"  returni( _RPAREN );
"["  returni( _LSQUARE );
"]"  returni( _RSQUARE );
">"  returni( _GT );
"<"  returni( _LT );
"="  returni( _EQ );
"<>" returni( _NEQ );
">=" returni( _GE );
"<=" returni( _LE );
";"  returni( _SEMICOLON );
"."  returni( _PERIOD );
"*"  returni( _MULT );
"+"  returni( _PLUS );
"-"  returni( _SUB );
"^"  returni( _EXP );
"/"  returni( _DIV );
"/*"[^\*]*"*/" returni( _COMMENT );
[ ]  returni( _BLANK );
[\n] returni( _NEWLINE );
[\t] returni( _TAB );
.    returni( _ILLEGAL );

⌨️ 快捷键说明

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