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

📄 qexprlex.pas

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

// lexical analyzer template for Expression Parser

// global definitions:


{**************************************************}
{   Lexical analizer for Expression Parser         }
{   Copyright (c) 2002 by Ingenieria Construmap    }
{                      Developed by Alfonso Moreno }
{**************************************************}

unit QExprLex;

{$I XQ_FLAG.INC}
interface

uses
  SysUtils, QLexLib, QExprYacc;

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
//===============================================
  type
    TRWord = record
       rword: string[14];
       token: smallint;
    end;

  const
    rwords : array [1..26] 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)
    );

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;





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

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

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

  if IsKeyword(yylval.yystring, token) then
    returni(token)
  else
    returni(_IDENTIFIER);
  2:

  begin
    // extended identifier for using in fields with same name as reserved word
    yylval.yystring := Copy(yylval.yystring, 2, yyTextLen - 2);
    returni( _IDENTIFIER );
  end;

  3:
                     returni( _NUMERIC );

  4:
                     returni( _UINTEGER );

  5:
                     returni( _SINTEGER );

  6:

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

  7:

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

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

  if Length( yylval.yystring ) >= 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, yyTextLen - 2)));
    ShortDateFormat := SaveDate;
    returni(_NUMERIC);
  end;
  10:
     returni( _COMA );
  11:
     returni( _LPAREN );
  12:
     returni( _RPAREN );
  13:
     returni( _GT );
  14:
     returni( _LT );
  15:
     returni( _EQ );
  16:
     returni( _NEQ );
  17:
     returni( _GE );
  18:
     returni( _LE );
  19:
     returni( _PERIOD );
  20:
     returni( _COLON );
  21:
     returni( _MULT );
  22:
     returni( _PLUS );
  23:
     returni( _SUB );
  24:
     returni( _EXP );
  25:
     returni( _DIV );
  26:
               returni( _COMMENT );
  27:
     returni( _BLANK );
  28:
     returni( _NEWLINE );
  29:
     returni( _TAB );
  30:
     returni( _ILLEGAL );
  end;
end(*yyaction*);

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

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

const

yynmarks   = 55;
yynmatches = 55;
yyntrans   = 89;
yynstates  = 48;

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

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

yyt : array [1..yyntrans] of YYTrec = (
{ 0: }
  ( cc: [ #1..#8,#11..#31,'!','%','&',';','?','@','\',']',
            '_','`','{'..#127 ]; s: 25),
  ( cc: [ #9 ]; s: 24),
  ( cc: [ #10 ]; s: 23),
  ( cc: [ ' ' ]; s: 22),
  ( cc: [ '"' ]; s: 9),
  ( cc: [ '#' ]; s: 10),
  ( cc: [ '$' ]; s: 7),
  ( cc: [ '''' ]; s: 8),
  ( cc: [ '(' ]; s: 12),
  ( cc: [ ')' ]; s: 13),
  ( cc: [ '*' ]; s: 18),
  ( cc: [ '+' ]; s: 19),
  ( cc: [ ',' ]; s: 11),
  ( cc: [ '-' ]; s: 4),
  ( cc: [ '.' ]; s: 6),
  ( cc: [ '/' ]; s: 21),
  ( cc: [ '0'..'9' ]; s: 5),
  ( cc: [ ':' ]; s: 17),
  ( cc: [ '<' ]; s: 15),
  ( cc: [ '=' ]; s: 16),
  ( cc: [ '>' ]; s: 14),
  ( cc: [ 'A'..'Z','a'..'z',#128..#255 ]; s: 2),
  ( cc: [ '[' ]; s: 3),
  ( cc: [ '^' ]; s: 20),

⌨️ 快捷键说明

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