623 lines
15 KiB
ObjectPascal
623 lines
15 KiB
ObjectPascal
// ============================================================================
|
|
// This file is generated by the Delphi Parser Generator.
|
|
// ----------------------------------------------------------------------------
|
|
// DPG version: 2.1.0.0r
|
|
// Grammar: dpglib.tokenLexer.g
|
|
// ============================================================================
|
|
unit dpglib.TokenLexer;
|
|
|
|
interface
|
|
|
|
uses
|
|
System.Classes,
|
|
dpglib.TokenLexerTokens,
|
|
dpgrtl.lexer,
|
|
dpgrtl.types,
|
|
System.SysUtils;
|
|
|
|
type
|
|
// =========================================================================
|
|
// Class TTokenLexer declaration
|
|
// =========================================================================
|
|
TTokenLexer = class( TLexer)
|
|
|
|
public // Protected grammar rules
|
|
// Must callable from parser too
|
|
procedure mDIGIT ( pCreate: boolean);
|
|
procedure mXDIGIT ( pCreate: boolean);
|
|
|
|
public // Public grammar rules
|
|
procedure mLPAREN ( pCreate: boolean);
|
|
procedure mRPAREN ( pCreate: boolean);
|
|
procedure mASSIGN ( pCreate: boolean);
|
|
procedure mSTRING ( pCreate: boolean);
|
|
procedure mID ( pCreate: boolean);
|
|
procedure mINT ( pCreate: boolean);
|
|
procedure mWS ( pCreate: boolean);
|
|
procedure mSLCOMMENT ( pCreate: boolean);
|
|
procedure mMLCOMMENT ( pCreate: boolean);
|
|
|
|
public
|
|
function NextToken: IToken; override;
|
|
end;
|
|
|
|
implementation
|
|
uses
|
|
dpgrtl.exception,
|
|
dpgrtl.token;
|
|
|
|
|
|
// ============================================================================
|
|
// mLPAREN
|
|
// ============================================================================
|
|
procedure TTokenLexer.mLPAREN( pCreate: boolean);
|
|
var
|
|
_begin: integer;
|
|
_save: integer;
|
|
_token: IToken;
|
|
_ttype: integer;
|
|
|
|
begin
|
|
_begin := Length( TokenText) +1;
|
|
_token := nil;
|
|
_ttype := TT_LPAREN;
|
|
|
|
match('(');
|
|
|
|
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
|
begin
|
|
_token := makeToken( _ttype);
|
|
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
|
end;
|
|
|
|
ReturnToken := _token;
|
|
end;
|
|
|
|
// ============================================================================
|
|
// mRPAREN
|
|
// ============================================================================
|
|
procedure TTokenLexer.mRPAREN( pCreate: boolean);
|
|
var
|
|
_begin: integer;
|
|
_save: integer;
|
|
_token: IToken;
|
|
_ttype: integer;
|
|
|
|
begin
|
|
_begin := Length( TokenText) +1;
|
|
_token := nil;
|
|
_ttype := TT_RPAREN;
|
|
|
|
match(')');
|
|
|
|
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
|
begin
|
|
_token := makeToken( _ttype);
|
|
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
|
end;
|
|
|
|
ReturnToken := _token;
|
|
end;
|
|
|
|
// ============================================================================
|
|
// mASSIGN
|
|
// ============================================================================
|
|
procedure TTokenLexer.mASSIGN( pCreate: boolean);
|
|
var
|
|
_begin: integer;
|
|
_save: integer;
|
|
_token: IToken;
|
|
_ttype: integer;
|
|
|
|
begin
|
|
_begin := Length( TokenText) +1;
|
|
_token := nil;
|
|
_ttype := TT_ASSIGN;
|
|
|
|
match('=');
|
|
|
|
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
|
begin
|
|
_token := makeToken( _ttype);
|
|
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
|
end;
|
|
|
|
ReturnToken := _token;
|
|
end;
|
|
|
|
// ============================================================================
|
|
// mSTRING
|
|
// ============================================================================
|
|
procedure TTokenLexer.mSTRING( pCreate: boolean);
|
|
var
|
|
_begin: integer;
|
|
_save: integer;
|
|
_token: IToken;
|
|
_ttype: integer;
|
|
|
|
begin
|
|
_begin := Length( TokenText) +1;
|
|
_token := nil;
|
|
_ttype := TT_STRING;
|
|
|
|
match('"');
|
|
|
|
while(true) do
|
|
begin
|
|
if (( LA(1) in [#1..'!','#'..#255])) then
|
|
begin
|
|
matchNot('"');
|
|
end
|
|
|
|
else
|
|
break;
|
|
end;
|
|
|
|
match('"');
|
|
|
|
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
|
begin
|
|
_token := makeToken( _ttype);
|
|
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
|
end;
|
|
|
|
ReturnToken := _token;
|
|
end;
|
|
|
|
// ============================================================================
|
|
// mDIGIT
|
|
// ============================================================================
|
|
procedure TTokenLexer.mDIGIT( pCreate: boolean);
|
|
var
|
|
_begin: integer;
|
|
_save: integer;
|
|
_token: IToken;
|
|
_ttype: integer;
|
|
|
|
begin
|
|
_begin := Length( TokenText) +1;
|
|
_token := nil;
|
|
_ttype := TT_DIGIT;
|
|
|
|
match( ['0'..'9']);
|
|
|
|
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
|
begin
|
|
_token := makeToken( _ttype);
|
|
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
|
end;
|
|
|
|
ReturnToken := _token;
|
|
end;
|
|
|
|
// ============================================================================
|
|
// mXDIGIT
|
|
// ============================================================================
|
|
procedure TTokenLexer.mXDIGIT( pCreate: boolean);
|
|
var
|
|
_begin: integer;
|
|
_save: integer;
|
|
_token: IToken;
|
|
_ttype: integer;
|
|
|
|
begin
|
|
_begin := Length( TokenText) +1;
|
|
_token := nil;
|
|
_ttype := TT_XDIGIT;
|
|
|
|
if (( LA(1) in ['0'..'9'])) then
|
|
begin
|
|
match( ['0'..'9']);
|
|
end
|
|
|
|
else if (( LA(1) in ['a'..'f'])) then
|
|
begin
|
|
match( ['a'..'f']);
|
|
end
|
|
|
|
else if (( LA(1) in ['A'..'F'])) then
|
|
begin
|
|
match( ['A'..'F']);
|
|
end
|
|
|
|
else
|
|
Raise EMismatchedChar.Create( LA(1), ['0'..'9','A'..'F','a'..'f'], InputState.FileName, InputState.Line, InputState.Column);
|
|
|
|
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
|
begin
|
|
_token := makeToken( _ttype);
|
|
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
|
end;
|
|
|
|
ReturnToken := _token;
|
|
end;
|
|
|
|
// ============================================================================
|
|
// mID
|
|
// ============================================================================
|
|
procedure TTokenLexer.mID( pCreate: boolean);
|
|
var
|
|
_begin: integer;
|
|
_save: integer;
|
|
_token: IToken;
|
|
_ttype: integer;
|
|
|
|
begin
|
|
_begin := Length( TokenText) +1;
|
|
_token := nil;
|
|
_ttype := TT_ID;
|
|
|
|
if (( LA(1) in ['a'..'z'])) then
|
|
begin
|
|
match( ['a'..'z']);
|
|
end
|
|
|
|
else if (( LA(1) in ['A'..'Z'])) then
|
|
begin
|
|
match( ['A'..'Z']);
|
|
end
|
|
|
|
else
|
|
Raise EMismatchedChar.Create( LA(1), ['A'..'Z','a'..'z'], InputState.FileName, InputState.Line, InputState.Column);
|
|
|
|
while(true) do
|
|
begin
|
|
if (( LA(1) in ['a'..'z'])) then
|
|
begin
|
|
match( ['a'..'z']);
|
|
end
|
|
|
|
else if (( LA(1) in ['A'..'Z'])) then
|
|
begin
|
|
match( ['A'..'Z']);
|
|
end
|
|
|
|
else if (( LA(1) in ['_'])) then
|
|
begin
|
|
match('_');
|
|
end
|
|
|
|
else if (( LA(1) in ['0'..'9'])) then
|
|
begin
|
|
match( ['0'..'9']);
|
|
end
|
|
|
|
else
|
|
break;
|
|
end;
|
|
|
|
|
|
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
|
begin
|
|
_token := makeToken( _ttype);
|
|
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
|
end;
|
|
|
|
ReturnToken := _token;
|
|
end;
|
|
|
|
// ============================================================================
|
|
// mINT
|
|
// ============================================================================
|
|
procedure TTokenLexer.mINT( pCreate: boolean);
|
|
var
|
|
_begin: integer;
|
|
_cnt_15: integer;
|
|
_save: integer;
|
|
_token: IToken;
|
|
_ttype: integer;
|
|
|
|
begin
|
|
_begin := Length( TokenText) +1;
|
|
_token := nil;
|
|
_ttype := TT_INT;
|
|
|
|
_cnt_15 := 0;
|
|
|
|
while(true) do
|
|
begin
|
|
if (( LA(1) in ['0'..'9'])) then
|
|
begin
|
|
mDIGIT(false);
|
|
end
|
|
|
|
else
|
|
begin
|
|
if _cnt_15 >= 1 then
|
|
break
|
|
else
|
|
Raise EMismatchedChar.Create( LA(1), ['0'..'9'], InputState.FileName, InputState.Line, InputState.Column);
|
|
end;
|
|
|
|
INC(_cnt_15);
|
|
end;
|
|
|
|
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
|
begin
|
|
_token := makeToken( _ttype);
|
|
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
|
end;
|
|
|
|
ReturnToken := _token;
|
|
end;
|
|
|
|
// ============================================================================
|
|
// mWS
|
|
// ============================================================================
|
|
procedure TTokenLexer.mWS( pCreate: boolean);
|
|
var
|
|
_begin: integer;
|
|
_save: integer;
|
|
_token: IToken;
|
|
_ttype: integer;
|
|
|
|
begin
|
|
_begin := Length( TokenText) +1;
|
|
_token := nil;
|
|
_ttype := TT_WS;
|
|
|
|
if (( LA(1) in [#13]) and (LA(2) in [#10])) then
|
|
begin
|
|
match(#13);
|
|
match(#10);
|
|
newLine;
|
|
end
|
|
|
|
else if (( LA(1) in [' '])) then
|
|
begin
|
|
match(' ');
|
|
end
|
|
|
|
else if (( LA(1) in [#9])) then
|
|
begin
|
|
match(#9);
|
|
end
|
|
|
|
else if (( LA(1) in [#13])) then
|
|
begin
|
|
match(#13);
|
|
newLine;
|
|
end
|
|
|
|
else if (( LA(1) in [#10])) then
|
|
begin
|
|
match(#10);
|
|
newLine;
|
|
end
|
|
|
|
else
|
|
Raise EMismatchedChar.Create( LA(1), [#9..#10,#13,' '], InputState.FileName, InputState.Line, InputState.Column);
|
|
_ttype := TT_SKIP;
|
|
|
|
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
|
begin
|
|
_token := makeToken( _ttype);
|
|
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
|
end;
|
|
|
|
ReturnToken := _token;
|
|
end;
|
|
|
|
// ============================================================================
|
|
// mSLCOMMENT
|
|
// ============================================================================
|
|
procedure TTokenLexer.mSLCOMMENT( pCreate: boolean);
|
|
var
|
|
_begin: integer;
|
|
_save: integer;
|
|
_token: IToken;
|
|
_ttype: integer;
|
|
|
|
begin
|
|
_begin := Length( TokenText) +1;
|
|
_token := nil;
|
|
_ttype := TT_SLCOMMENT;
|
|
|
|
match('//');
|
|
|
|
while(true) do
|
|
begin
|
|
if (( LA(1) in [#1..#9,#11..#12,#14..#255])) then
|
|
begin
|
|
match( [#1..#9,#11..#12,#14..#255]);
|
|
end
|
|
|
|
else
|
|
break;
|
|
end;
|
|
|
|
if (( LA(1) in [#13]) and (LA(2) in [#10])) then
|
|
begin
|
|
match(#13);
|
|
match(#10);
|
|
newLine;
|
|
end
|
|
|
|
else if (( LA(1) in [#13])) then
|
|
begin
|
|
match(#13);
|
|
newLine;
|
|
end
|
|
|
|
else if (( LA(1) in [#10])) then
|
|
begin
|
|
match(#10);
|
|
newLine;
|
|
end
|
|
|
|
else
|
|
Raise EMismatchedChar.Create( LA(1), [#10,#13], InputState.FileName, InputState.Line, InputState.Column);
|
|
_ttype := TT_SKIP;
|
|
|
|
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
|
begin
|
|
_token := makeToken( _ttype);
|
|
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
|
end;
|
|
|
|
ReturnToken := _token;
|
|
end;
|
|
|
|
// ============================================================================
|
|
// mMLCOMMENT
|
|
// ============================================================================
|
|
procedure TTokenLexer.mMLCOMMENT( pCreate: boolean);
|
|
var
|
|
_begin: integer;
|
|
_save: integer;
|
|
_token: IToken;
|
|
_ttype: integer;
|
|
|
|
begin
|
|
_begin := Length( TokenText) +1;
|
|
_token := nil;
|
|
_ttype := TT_MLCOMMENT;
|
|
|
|
match('(*');
|
|
|
|
while(true) do
|
|
begin
|
|
// non-greedy exit test
|
|
if( LA(1) in ['*']) and (LA(2) in [')']) then
|
|
break;
|
|
|
|
if (( LA(1) in [#13]) and (LA(2) in [#10])) then
|
|
begin
|
|
match(#13);
|
|
match(#10);
|
|
newLine;
|
|
end
|
|
|
|
else if (( LA(1) in [#13])) then
|
|
begin
|
|
match(#13);
|
|
newLine;
|
|
end
|
|
|
|
else if (( LA(1) in [#10])) then
|
|
begin
|
|
match(#10);
|
|
newLine;
|
|
end
|
|
|
|
else if (( LA(1) in [#1..#9,#11..#12,#14..#255])) then
|
|
begin
|
|
match( [#1..#9,#11..#12,#14..#255]);
|
|
end
|
|
|
|
else
|
|
break;
|
|
end;
|
|
|
|
match('*)');
|
|
_ttype := TT_SKIP;
|
|
|
|
if (_ttype <> TT_SKIP) and (pCreate = true) then
|
|
begin
|
|
_token := makeToken( _ttype);
|
|
_token.TokenText := Copy( TokenText, _begin, Length(TokenText)-_begin+1);
|
|
end;
|
|
|
|
ReturnToken := _token;
|
|
end;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// NextToken
|
|
// ----------------------------------------------------------------------------
|
|
function TTokenLexer.NextToken : IToken;
|
|
var
|
|
_first : TCharSet;
|
|
|
|
begin
|
|
_first := [#9..#10,#13,' ','"','('..')','/'..'9','=','A'..'Z','a'..'z'];
|
|
|
|
while( true) do
|
|
begin
|
|
ResetText;
|
|
|
|
try
|
|
if (( LA(1) in ['(']) and (LA(2) in ['*'])) then
|
|
begin
|
|
mMLCOMMENT(true);
|
|
result := ReturnToken;
|
|
end
|
|
|
|
else if (( LA(1) in ['('])) then
|
|
begin
|
|
mLPAREN(true);
|
|
result := ReturnToken;
|
|
end
|
|
|
|
else if (( LA(1) in [')'])) then
|
|
begin
|
|
mRPAREN(true);
|
|
result := ReturnToken;
|
|
end
|
|
|
|
else if (( LA(1) in ['='])) then
|
|
begin
|
|
mASSIGN(true);
|
|
result := ReturnToken;
|
|
end
|
|
|
|
else if (( LA(1) in ['"'])) then
|
|
begin
|
|
mSTRING(true);
|
|
result := ReturnToken;
|
|
end
|
|
|
|
else if (( LA(1) in ['A'..'Z','a'..'z'])) then
|
|
begin
|
|
mID(true);
|
|
result := ReturnToken;
|
|
end
|
|
|
|
else if (( LA(1) in ['0'..'9'])) then
|
|
begin
|
|
mINT(true);
|
|
result := ReturnToken;
|
|
end
|
|
|
|
else if (( LA(1) in [#9..#10,#13,' '])) then
|
|
begin
|
|
mWS(true);
|
|
result := ReturnToken;
|
|
end
|
|
|
|
else if (( LA(1) in ['/'])) then
|
|
begin
|
|
mSLCOMMENT(true);
|
|
result := ReturnToken;
|
|
end
|
|
|
|
else
|
|
begin
|
|
if LA(1) = EOF_CHAR then
|
|
begin
|
|
uponEof;
|
|
result := TToken.Create(TT_EOF);
|
|
end
|
|
|
|
else
|
|
Raise EMismatchedChar.Create(LA(1), _first, InputState.FileName, InputState.Line, InputState.Column);
|
|
end;
|
|
|
|
// --------------------------------------------------------------
|
|
// If we found a SKIP token, then try again...
|
|
// --------------------------------------------------------------
|
|
if result = nil then
|
|
continue;
|
|
|
|
// --------------------------------------------------------------
|
|
// Now we have a valid token, so exit the function
|
|
// --------------------------------------------------------------
|
|
break;
|
|
|
|
except
|
|
Raise;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
end.
|