📄 ezexprlex.pas
字号:
// lexical analyzer template for Expression Parser
// global definitions:
{**************************************************}
{ 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;
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, Length(yylval.yystring) - 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
yymore
else
begin
unget_char(c);
returni( _STRING );
end;
end;
8:
begin
c := get_char;
if c = #34 then
yymore
else
begin
unget_char(c);
returni( _STRING );
end;
end;
9:
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;
10:
returni( _COMA );
11:
returni( _LPAREN );
12:
returni( _RPAREN );
13:
returni( _LSQUARE );
14:
returni( _RSQUARE );
15:
returni( _GT );
16:
returni( _LT );
17:
returni( _EQ );
18:
returni( _NEQ );
19:
returni( _GE );
20:
returni( _LE );
21:
returni( _SEMICOLON );
22:
returni( _PERIOD );
23:
returni( _MULT );
24:
returni( _PLUS );
25:
returni( _SUB );
26:
returni( _EXP );
27:
returni( _DIV );
28:
returni( _COMMENT );
29:
returni( _BLANK );
30:
returni( _NEWLINE );
31:
returni( _TAB );
32:
returni( _ILLEGAL );
end;
end(*yyaction*);
function TExprLexer.yylex : Integer;
(* DFA table: *)
type YYTRec = record
cc : set of Char;
s : SmallInt;
end;
const
yynmarks = 58;
yynmatches = 58;
yyntrans = 90;
yynstates = 49;
yyk : array [1..yynmarks] of SmallInt = (
{ 0: }
{ 1: }
{ 2: }
1,
32,
{ 3: }
13,
32,
{ 4: }
25,
32,
{ 5: }
4,
32,
{ 6: }
22,
32,
{ 7: }
32,
{ 8: }
32,
{ 9: }
32,
{ 10: }
32,
{ 11: }
10,
32,
{ 12: }
11,
32,
{ 13: }
12,
32,
{ 14: }
14,
32,
{ 15: }
15,
32,
{ 16: }
16,
32,
{ 17: }
17,
32,
{ 18: }
21,
32,
{ 19: }
23,
32,
{ 20: }
24,
32,
{ 21: }
26,
32,
{ 22: }
27,
32,
{ 23: }
29,
32,
{ 24: }
30,
{ 25: }
31,
32,
{ 26: }
32,
{ 27: }
1,
{ 28: }
{ 29: }
5,
{ 30: }
4,
{ 31: }
3,
{ 32: }
3,
{ 33: }
6,
{ 34: }
{ 35: }
7,
{ 36: }
{ 37: }
8,
{ 38: }
{ 39: }
9,
{ 40: }
19,
{ 41: }
18,
{ 42: }
20,
{ 43: }
{ 44: }
2,
{ 45: }
{ 46: }
{ 47: }
{ 48: }
28
);
yym : array [1..yynmatches] of SmallInt = (
{ 0: }
{ 1: }
{ 2: }
1,
32,
{ 3: }
13,
32,
{ 4: }
25,
32,
{ 5: }
4,
32,
{ 6: }
22,
32,
{ 7: }
32,
{ 8: }
32,
{ 9: }
32,
{ 10: }
32,
{ 11: }
10,
32,
{ 12: }
11,
32,
{ 13: }
12,
32,
{ 14: }
14,
32,
{ 15: }
15,
32,
{ 16: }
16,
32,
{ 17: }
17,
32,
{ 18: }
21,
32,
{ 19: }
23,
32,
{ 20: }
24,
32,
{ 21: }
26,
32,
{ 22: }
27,
32,
{ 23: }
29,
32,
{ 24: }
30,
{ 25: }
31,
32,
{ 26: }
32,
{ 27: }
1,
{ 28: }
{ 29: }
5,
{ 30: }
4,
{ 31: }
3,
{ 32: }
3,
{ 33: }
6,
{ 34: }
{ 35: }
7,
{ 36: }
{ 37: }
8,
{ 38: }
{ 39: }
9,
{ 40: }
19,
{ 41: }
18,
{ 42: }
20,
{ 43: }
{ 44: }
2,
{ 45: }
{ 46: }
{ 47: }
{ 48: }
28
);
yyt : array [1..yyntrans] of YYTrec = (
{ 0: }
( cc: [ #1..#8,#11..#31,'!','%','&',':','?','@','\',
'_','`','{'..#127 ]; s: 26),
( cc: [ #9 ]; s: 25),
( cc: [ #10 ]; s: 24),
( cc: [ ' ' ]; s: 23),
( cc: [ '"' ]; s: 9),
( cc: [ '#' ]; s: 10),
( cc: [ '$' ]; s: 7),
( cc: [ '''' ]; s: 8),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -