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

📄 xqlex.pas

📁 TxQuery is an SQL engine implemented in a TDataSet descendant component, that can parse SQL syntax,
💻 PAS
📖 第 1 页 / 共 2 页
字号:

// lexical analyzer template for TxQuery

// global definitions:


{**********************************************}
{   Lexical analizer for TxQuery component     }
{   Copyright (c) 2002 by Alfonso Moreno       }
{**********************************************}

unit XQLex;

{$I XQ_FLAG.INC}
interface

uses
  SysUtils, Classes, QLexLib, xqYacc;

type
  TxqLexer = Class( TCustomLexer)
  private
    FIsWhereActive : Boolean;
    FDateFormat    : String;
    FIgnoreBadDates: Boolean;
  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;

    property IsWhereActive: Boolean read FIsWhereActive write FIsWhereActive;
    property DateFormat: String read FDateFormat write FDateFormat;
    property IgnoreBadDates: Boolean read FIgnoreBadDates write FIgnoreBadDates;
  end;

//===============================================
// reserved words definition
//===============================================
  type
    TRWord = record
       rword: string[10];
       token: smallint;
    end;

  const
    rwords : array [1..101] of TRword = (
    (rword:'TOP';          token: RW_TOP),
    (rword:'SELECT';       token: RW_SELECT),
    (rword:'DISTINCT';     token: RW_DISTINCT),
    (rword:'TRUE';         token: RW_TRUE),
    (rword:'FALSE';        token: RW_FALSE),
    (rword:'AND';          token: RW_AND),
    (rword:'OR';           token: RW_OR),
    (rword:'NOT';          token: RW_NOT),
    (rword:'FROM';         token: RW_FROM),
    (rword:'WHERE';        token: RW_WHERE),
    (rword:'ORDER';        token: RW_ORDER),
    (rword:'BY';           token: RW_BY),
    (rword:'ASC';          token: RW_ASC),
    (rword:'DESC';         token: RW_DESC),
    (rword:'AS';           token: RW_AS),
    (rword:'INNER';        token: RW_INNER),
    (rword:'OUTER';        token: RW_OUTER),
    (rword:'FULL';         token: RW_FULL),
    (rword:'JOIN';         token: RW_JOIN),
    (rword:'ON';           token: RW_ON),
    (rword:'GROUP';        token: RW_GROUP),
    (rword:'ANY';          token: RW_ANY),
    (rword:'ALL';          token: RW_ALL),
    (rword:'SUM';          token: RW_SUM),
    (rword:'AVG';          token: RW_AVG),
    (rword:'COUNT';        token: RW_COUNT),
    (rword:'MIN';          token: RW_MIN),
    (rword:'MAX';          token: RW_MAX),
    (rword:'STDEV';        token: RW_STDEV),
    (rword:'BETWEEN';      token: RW_BETWEEN),
    (rword:'IN';           token: RW_IN),
    (rword:'LIKE';         token: RW_LIKE),
    (rword:'LEFT';         token: RW_LEFT),
    (rword:'RIGHT';        token: RW_RIGHT),
    (rword:'HAVING';       token: RW_HAVING),
    (rword:'LEADING';      token: RW_LEADING),
    (rword:'TRAILING';     token: RW_TRAILING),
    (rword:'BOTH';         token: RW_BOTH),
    (rword:'TRIM';         token: RW_TRIM),
    (rword:'EXTRACT';      token: RW_EXTRACT),
    (rword:'YEAR';         token: RW_YEAR),
    (rword:'MONTH';        token: RW_MONTH),
    (rword:'DAY';          token: RW_DAY),
    (rword:'HOUR';         token: RW_HOUR),
    (rword:'MINUTE';       token: RW_MINUTE),
    (rword:'SECOND';       token: RW_SECOND),
    (rword:'SUBSTRING';    token: RW_SUBSTRING),
    (rword:'FOR';          token: RW_FOR),
    (rword:'DELETE';       token: RW_DELETE),
    (rword:'UPDATE';       token: RW_UPDATE),
    (rword:'INSERT';       token: RW_INSERT),
    (rword:'INTO';         token: RW_INTO),
    (rword:'VALUES';       token: RW_VALUES),
    (rword:'SET';          token: RW_SET),
    (rword:'CAST';         token: RW_CAST),
    (rword:'CHAR';         token: RW_CHAR),
    (rword:'INTEGER';      token: RW_INTEGER),
    (rword:'BOOLEAN';      token: RW_BOOLEAN),
    (rword:'DATE';         token: RW_DATE),
    (rword:'DATETIME';     token: RW_DATETIME),
    (rword:'TIME';         token: RW_TIME),
    (rword:'FLOAT';        token: RW_FLOAT),
    (rword:'NUMERIC';      token: RW_FLOAT),
    (rword:'ESCAPE';       token: RW_ESCAPE),
    (rword:'CREATE';       token: RW_CREATE),
    (rword:'TABLE';        token: RW_TABLE),
    (rword:'SMALLINT';     token: RW_SMALLINT),
    (rword:'MONEY';        token: RW_MONEY),
    (rword:'AUTOINC';      token: RW_AUTOINC),
    (rword:'PRIMARY';      token: RW_PRIMARY),
    (rword:'KEY';          token: RW_KEY),
    (rword:'BLOB';         token: RW_BLOB),
    (rword:'INDEX';        token: RW_INDEX),
    (rword:'UNIQUE';       token: RW_UNIQUE),
    (rword:'DROP';         token: RW_DROP),
    (rword:'TRANSFORM';    token: RW_TRANSFORM),
    (rword:'PIVOT';        token: RW_PIVOT),
    (rword:'UNION';        token: RW_UNION),
    (rword:'WITH';         token: RW_WITH),
    (rword:'IS';           token: RW_IS),
    (rword:'NULL';         token: RW_NULL),
    (rword:'MOD';          token: RW_MOD),
    (rword:'DIV';          token: RW_IDIV),
    (rword:'SHL';          token: RW_SHL),
    (rword:'SHR';          token: RW_SHR),
    (rword:'ALTER';        token: RW_ALTER),
    (rword:'COLUMN';       token: RW_COLUMN),
    (rword:'ADD';          token: RW_ADD),
    (rword:'APPEND';       token: RW_APPEND),
    (rword:'CASE';         token: RW_CASE),
    (rword:'WHEN';         token: RW_WHEN),
    (rword:'THEN';         token: RW_THEN),
    (rword:'ELSE';         token: RW_ELSE),
    (rword:'END';          token: RW_END),
    (rword:'PACK';         token: RW_PACK),
    (rword:'ZAP';          token: RW_ZAP),
    (rword:'REINDEX';      token: RW_REINDEX),
    (rword:'FIELDS';       token: RW_FIELDS),
    (rword:'USING';        token: RW_USING),
    (rword:'RANGE';        token: RW_RANGE),
    (rword:'TO';           token: RW_TO)

    );

implementation

uses xqConsts, xquery;

function TxqLexer.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 TxqLexer.commenteof;
begin
  writeln(yyErrorfile, 'unexpected EOF inside comment at line '
                       +intToStr( yylineno));
end;





procedure TXQLexer.yyaction ( yyruleno : Integer );
  (* local definitions: *)

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

      Function ReturnDate( const ADate: String ): string;
      begin
        SaveDate := ShortDateFormat;
        if Length( Self.FDateFormat ) = 0 then
          Self.FDateFormat := ShortDateFormat;//SDefaultDateFormat;
        ShortDateFormat := Self.FDateFormat;
        try
           Result := FloatToStr( StrToDate( ADate ) );
           if FIsWhereActive then
              Result := 'DummyDate(' + Result + ')';
           ShortDateFormat := SaveDate;
           returni( _NUMERIC );
        except
           if not FIgnoreBadDates then
           begin
              FIgnoreBadDates:= False;
              raise;
           end;
        end;
      end;

begin
  GetyyText (yylval.yystring);
  (* actions: *)
  case yyruleno of
  1:

  begin
    If AnsiCompareText( yylval.yystring, 'NOW' ) = 0 Then
    Begin
      SaveDate := ShortDateFormat;
      if Length( Self.FDateFormat ) = 0 then
         Self.FDateFormat := ShortDateFormat;//SDefaultDateFormat;
      ShortDateFormat := Self.FDateFormat;
      try
         yylval.yystring := FloatToStr( Now );
         if FIsWhereActive then
            yylval.yystring := 'DummyDate(' + yylval.yystring + ')';
         ShortDateFormat := SaveDate;
         returni( _NUMERIC );
      except
         if not FIgnoreBadDates then
         begin
            FIgnoreBadDates:= False;
            raise;
         end;
      end;
      Exit;
    End;
    if IsKeyword(yylval.yystring, token) then
    begin
      if token = RW_WHERE then
        FIsWhereActive:= True
      else if FIsWhereActive and ( (token = RW_GROUP) or
         (token =RW_ORDER) or (token = RW_SELECT) or (token =RW_PIVOT) ) then
        FIsWhereActive := False;

        returni(token);
    end
    else
      returni(_IDENTIFIER);
  end;
  2:
               returni( _COMMENT );
  3:
               returni( _COMMENT );
  4:
               returni( _COMMENT );
  5:

  begin
    // extended identifier
    //yylval.yystring := yylval.yystring;
    returni( _IDENTIFIER );
  end;

  6:
                     returni( _NUMERIC );

  7:
                     returni( _UINTEGER );

  8:
                     returni( _SINTEGER );

  9:

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

  10:

  begin
    c := get_char;
    unget_char(c);
    if c = #39 then
      yymore
    else
      returni( _STRING );
  end;
  11:

  begin
    c := get_char;
    unget_char(c);
    if c = #34 then
      yymore
    else
      returni( _STRING );
  end;
  12:

  begin
    // previously this "#"{DIGIT}{1,2}"/"{DIGIT}{1,2}"/"({DIGIT}{2}|{DIGIT}{4})"#"
    if yytextlen >= 10 then
    begin
    yylval.yystring := ReturnDate( Copy( yylval.yystring, 2, yyTextLen - 2) );
    end;
  end;
  13:
     returni( _COMA );
  14:
     returni( _LPAREN );
  15:
     returni( _RPAREN );
  16:
     returni( _LSQUARE );
  17:
     returni( _RSQUARE );
  18:
     returni( _GT );
  19:
     returni( _LT );
  20:
     returni( _PERIOD );
  21:
     returni( _COLON );
  22:
     returni( _SEMICOLON );
  23:
     returni( _EQ );
  24:
     returni( _MULT );
  25:
     returni( _PLUS );
  26:
     returni( _SUB );
  27:
     returni( _EXP );
  28:
     returni( _DIV );
  29:
     returni( _NEQ );
  30:
     returni( _GE );
  31:
     returni( _LE );
  32:

  begin
    yylval.yystring := '+';
    returni( _PLUS );
  end;
  33:
     returni( _BLANK );
  34:
     returni( _NEWLINE );
  35:
     returni( _TAB );
  36:
     returni( _ILLEGAL );
  end;
end(*yyaction*);

function TXQLexer.yylex : Integer;
(* DFA table: *)

type YYTRec = record
                cc : set of Char;
                s  : SmallInt;
              end;

const

yynmarks   = 67;
yynmatches = 67;
yyntrans   = 112;
yynstates  = 62;

yyk : array [1..yynmarks] of SmallInt = (
  { 0: }
  { 1: }
  { 2: }
  1,
  36,
  { 3: }
  28,
  36,
  { 4: }
  16,
  36,
  { 5: }
  26,
  36,
  { 6: }
  25,
  36,
  { 7: }
  7,
  36,
  { 8: }
  20,
  36,
  { 9: }
  36,
  { 10: }
  36,
  { 11: }
  36,
  { 12: }
  36,
  { 13: }
  13,
  36,
  { 14: }
  14,
  36,
  { 15: }
  15,
  36,
  { 16: }
  17,
  36,
  { 17: }
  18,
  36,
  { 18: }
  19,
  36,
  { 19: }
  21,
  36,
  { 20: }
  22,
  36,
  { 21: }
  23,
  36,
  { 22: }
  24,
  36,
  { 23: }
  27,
  36,
  { 24: }
  36,
  { 25: }
  33,
  36,
  { 26: }
  34,
  { 27: }
  35,
  36,
  { 28: }
  36,
  { 29: }
  1,
  { 30: }
  { 31: }
  { 32: }
  { 33: }
  5,
  { 34: }
  { 35: }
  8,
  { 36: }
  7,
  { 37: }
  6,
  { 38: }
  6,
  { 39: }
  9,
  { 40: }
  { 41: }
  10,
  { 42: }
  { 43: }
  11,
  { 44: }
  { 45: }
  12,
  { 46: }
  30,
  { 47: }
  29,
  { 48: }
  31,
  { 49: }
  32,
  { 50: }
  { 51: }
  5,
  { 52: }
  { 53: }
  { 54: }
  { 55: }
  2,
  { 56: }
  { 57: }
  3,
  5,
  { 58: }
  4,
  { 59: }
  3
  { 60: }
  { 61: }
);

yym : array [1..yynmatches] of SmallInt = (
{ 0: }
{ 1: }
{ 2: }
  1,
  36,
{ 3: }
  28,
  36,
{ 4: }
  16,
  36,
{ 5: }
  26,
  36,
{ 6: }
  25,
  36,
{ 7: }
  7,
  36,
{ 8: }
  20,
  36,
{ 9: }
  36,
{ 10: }
  36,
{ 11: }
  36,
{ 12: }
  36,
{ 13: }
  13,
  36,
{ 14: }
  14,
  36,
{ 15: }
  15,
  36,
{ 16: }
  17,
  36,
{ 17: }
  18,
  36,
{ 18: }
  19,
  36,
{ 19: }
  21,
  36,
{ 20: }
  22,
  36,
{ 21: }
  23,
  36,
{ 22: }
  24,
  36,
{ 23: }
  27,
  36,
{ 24: }
  36,
{ 25: }
  33,
  36,
{ 26: }
  34,
{ 27: }
  35,
  36,
{ 28: }
  36,
{ 29: }
  1,
{ 30: }
{ 31: }
{ 32: }
{ 33: }
  5,
{ 34: }
{ 35: }
  8,
{ 36: }
  7,
{ 37: }
  6,
{ 38: }
  6,
{ 39: }
  9,
{ 40: }
{ 41: }
  10,
{ 42: }
{ 43: }
  11,
{ 44: }
{ 45: }
  12,
{ 46: }
  30,
{ 47: }
  29,
{ 48: }
  31,
{ 49: }
  32,
{ 50: }
{ 51: }
  5,
{ 52: }
{ 53: }
{ 54: }
{ 55: }
  2,
{ 56: }

⌨️ 快捷键说明

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