516 lines
14 KiB
ObjectPascal
516 lines
14 KiB
ObjectPascal
unit jtag.svfLex;
|
|
|
|
interface
|
|
uses
|
|
System.Classes,
|
|
Generics.Collections;
|
|
|
|
type
|
|
TTokenType =
|
|
(
|
|
TT_EOF,
|
|
TT_SKIP,
|
|
TT_SEMI,
|
|
TT_COMMENT,
|
|
TT_ID,
|
|
TT_NUMBER,
|
|
TT_HEX,
|
|
TT_LPAREN,
|
|
TT_RPAREN,
|
|
TT_STRING,
|
|
|
|
// SVF commands
|
|
LT_ENDIR, LT_ENDDR,
|
|
LT_HIR, LT_HDR,
|
|
LT_TIR, LT_TDR,
|
|
LT_SIR, LT_SDR,
|
|
|
|
LT_FREQUENCY,
|
|
LT_HZ,
|
|
LT_PIO,
|
|
LT_PIOMAP,
|
|
|
|
LT_RUNTEST,
|
|
LT_TCK,
|
|
LT_SCK,
|
|
LT_SEC,
|
|
LT_MAXIMUM,
|
|
LT_ENDSTATE,
|
|
|
|
LT_TDI,
|
|
LT_TDO,
|
|
LT_MASK,
|
|
LT_SMASK,
|
|
|
|
// SVX commands
|
|
LT_PRINT,
|
|
|
|
// TAP States
|
|
LT_STATE,
|
|
|
|
LT_DRSELECT,
|
|
LT_DRCAPTURE,
|
|
LT_DRSHIFT,
|
|
LT_DRUPDATE,
|
|
LT_DREXIT1,
|
|
LT_DREXIT2,
|
|
|
|
LT_IRSELECT,
|
|
LT_IRCAPTURE,
|
|
LT_IRSHIFT,
|
|
LT_IRUPDATE,
|
|
LT_IREXIT1,
|
|
LT_IREXIT2,
|
|
|
|
LT_RESET,
|
|
LT_IDLE,
|
|
LT_IRPAUSE,
|
|
LT_DRPAUSE,
|
|
|
|
|
|
LT_IN,
|
|
LT_OUT,
|
|
LT_INOUT,
|
|
|
|
LT_TRST,
|
|
LT_ON,
|
|
LT_OFF,
|
|
LT_Z,
|
|
LT_ABSENT
|
|
);
|
|
|
|
TTokenTypes = set of TTokenType;
|
|
|
|
TsvfToken = class
|
|
TokenType : TTokenType;
|
|
TokenText : AnsiString;
|
|
end;
|
|
|
|
TTokenMap = TDictionary<AnsiString,TTokenType>;
|
|
|
|
TAnsiCharSet = set of AnsiChar;
|
|
|
|
TsvfMode = ( SVF, HEX);
|
|
|
|
TsvfLEX = class
|
|
private
|
|
fBuffer : PAnsiChar;
|
|
fStart : PAnsiChar;
|
|
fForward : PAnsiChar;
|
|
|
|
fToken : TsvfToken;
|
|
fMode : TsvfMode;
|
|
|
|
fLiterals: TTokenMap;
|
|
|
|
private
|
|
procedure InitLiterals;
|
|
function CheckLiteral( ttext: AnsiString; ttype: TTokenType): TTokenType;
|
|
|
|
function MakeToken( ttype : TTokenType;
|
|
ttext : AnsiString): TsvfToken;
|
|
|
|
|
|
public
|
|
function NextToken : TsvfToken;
|
|
|
|
|
|
|
|
public
|
|
constructor Create( Stream: TStream);
|
|
destructor Destroy; override;
|
|
end;
|
|
|
|
implementation
|
|
uses
|
|
WinAPI.Windows,
|
|
System.SysUtils;
|
|
|
|
{ TsvfLEX }
|
|
|
|
// ================================================================================================
|
|
// Constructor
|
|
// ================================================================================================
|
|
constructor TsvfLEX.Create(Stream: TStream);
|
|
var
|
|
size : Int64;
|
|
token : TsvfToken;
|
|
|
|
begin
|
|
InitLiterals;
|
|
|
|
if Assigned( Stream) then
|
|
begin
|
|
size := Stream.Size - Stream.Position;
|
|
fBuffer := GetMemory(size+1);
|
|
|
|
Stream.Read(fBuffer^, size);
|
|
|
|
fMode := SVF;
|
|
fStart := fBuffer;
|
|
fForward := fBuffer;
|
|
fBuffer[size] := #0;
|
|
end
|
|
end;
|
|
|
|
destructor TsvfLEX.Destroy;
|
|
begin
|
|
FreeAndNil(fLiterals);
|
|
inherited;
|
|
end;
|
|
|
|
|
|
|
|
// @@@: Internals +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Internals
|
|
//
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ================================================================================================
|
|
// MakeToken
|
|
// ================================================================================================
|
|
function TsvfLEX.MakeToken(ttype: TTokenType; ttext: AnsiString): TsvfToken;
|
|
begin
|
|
result := TsvfToken.Create;
|
|
|
|
with result do
|
|
begin
|
|
TokenType := ttype;
|
|
|
|
if TokenType in [TT_COMMENT,TT_STRING]
|
|
then TokenText := ttext
|
|
else TokenText := UpperCase(ttext);
|
|
end
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// InitLiterals
|
|
// ================================================================================================
|
|
procedure TsvfLEX.InitLiterals;
|
|
begin
|
|
fLiterals := TTokenMap.Create;
|
|
|
|
fLiterals.Add('HIR', LT_HIR );
|
|
fLiterals.Add('HDR', LT_HDR );
|
|
fLiterals.Add('TIR', LT_TIR );
|
|
fLiterals.Add('TDR', LT_TDR );
|
|
fLiterals.Add('SIR', LT_SIR );
|
|
fLiterals.Add('SDR', LT_SDR );
|
|
fLiterals.Add('TDI', LT_TDI );
|
|
fLiterals.Add('TDO', LT_TDO );
|
|
fLiterals.Add('MASK', LT_MASK );
|
|
fLiterals.Add('SMASK', LT_SMASK );
|
|
|
|
fLiterals.Add('FREQUENCY', LT_FREQUENCY );
|
|
fLiterals.Add('HZ', LT_HZ );
|
|
|
|
fLiterals.Add('PIO', LT_PIO );
|
|
fLiterals.Add('PIOMAP', LT_PIOMAP );
|
|
|
|
fLiterals.Add('RUNTEST', LT_RUNTEST );
|
|
fLiterals.Add('TCK', LT_TCK );
|
|
fLiterals.Add('SCK', LT_SCK );
|
|
fLiterals.Add('SEC', LT_SEC );
|
|
fLiterals.Add('MAXIMUM', LT_MAXIMUM );
|
|
fLiterals.Add('ENDSTATE', LT_ENDSTATE );
|
|
|
|
fLiterals.Add('ENDIR', LT_ENDIR );
|
|
fLiterals.Add('ENDDR', LT_ENDDR );
|
|
fLiterals.Add('STATE', LT_STATE );
|
|
|
|
fLiterals.Add('RESET', LT_RESET );
|
|
fLiterals.Add('IDLE', LT_IDLE );
|
|
|
|
fLiterals.Add('DRSELECT', LT_DRSELECT );
|
|
fLiterals.Add('DRCAPTURE', LT_DRCAPTURE );
|
|
fLiterals.Add('DRSHIFT', LT_DRSHIFT );
|
|
fLiterals.Add('DRUPDATE', LT_DRUPDATE );
|
|
fLiterals.Add('DRPAUSE', LT_DRPAUSE );
|
|
fLiterals.Add('DREXIT1', LT_DREXIT1 );
|
|
fLiterals.Add('DREXIT2', LT_DREXIT2 );
|
|
|
|
fLiterals.Add('IRSELECT', LT_IRSELECT );
|
|
fLiterals.Add('IRCAPTURE', LT_DRCAPTURE );
|
|
fLiterals.Add('IRSHIFT', LT_IRSHIFT );
|
|
fLiterals.Add('IRUPDATE', LT_IRUPDATE );
|
|
fLiterals.Add('IRPAUSE', LT_IRPAUSE );
|
|
fLiterals.Add('IREXIT1', LT_IREXIT1 );
|
|
fLiterals.Add('IREXIT2', LT_IREXIT2 );
|
|
|
|
fLiterals.Add('IN', LT_IN );
|
|
fLiterals.Add('OUT', LT_OUT );
|
|
fLiterals.Add('INOUT', LT_INOUT );
|
|
|
|
fLiterals.Add('TRST', LT_TRST );
|
|
fLiterals.Add('ON', LT_ON );
|
|
fLiterals.Add('OFF', LT_OFF );
|
|
fLiterals.Add('Z', LT_Z );
|
|
fLiterals.Add('ABSENT', LT_ABSENT );
|
|
|
|
fLiterals.Add('PRINT', LT_PRINT );
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// CheckLiteral
|
|
// ================================================================================================
|
|
function TsvfLEX.CheckLiteral(ttext: AnsiString; ttype: TTokenType): TTokenType;
|
|
begin
|
|
result := ttype;
|
|
fLiterals.TryGetValue(ttext, result);
|
|
end;
|
|
|
|
|
|
|
|
// @@@: Interface +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Interface
|
|
//
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ================================================================================================
|
|
// NextToken
|
|
// ================================================================================================
|
|
function TsvfLEX.NextToken: TsvfToken;
|
|
|
|
function GetTokenText: AnsiString;
|
|
begin
|
|
SetLength( result, fForward-fStart);
|
|
MoveMemory( @result[1], fStart, fForward-fStart);
|
|
end;
|
|
|
|
var
|
|
ttext : AnsiString;
|
|
ttype : TTokenType;
|
|
|
|
begin
|
|
while true do
|
|
begin
|
|
result := nil;
|
|
fForward := fStart;
|
|
|
|
if fMode = HEX then
|
|
case fForward^ of
|
|
// ----------------------------------------------------
|
|
// HEX digits
|
|
// ----------------------------------------------------
|
|
'0'..'9','a'..'f','A'..'F':
|
|
begin
|
|
INC(fForward);
|
|
|
|
while fForward^ in ['0'..'9','a'..'f','A'..'F'] do
|
|
INC(fForward);
|
|
|
|
result := MakeToken( TT_HEX, GetTokenText);
|
|
fStart := fForward;
|
|
end;
|
|
|
|
// ----------------------------------------------------
|
|
// HEX end
|
|
// ----------------------------------------------------
|
|
')':
|
|
begin
|
|
fMode := SVF;
|
|
INC(fForward);
|
|
|
|
result := MakeToken( TT_RPAREN, '');
|
|
fStart := fForward;
|
|
end;
|
|
|
|
// ----------------------------------------------------
|
|
// SPACE,TAB
|
|
// ----------------------------------------------------
|
|
#32, #9: INC(fStart);
|
|
|
|
// ----------------------------------------------------
|
|
// CR/LF
|
|
// ----------------------------------------------------
|
|
#13,#10:
|
|
begin
|
|
INC(fStart);
|
|
|
|
while fStart^ in [#13,#10] do
|
|
INC(fStart)
|
|
end;
|
|
|
|
// ----------------------------------------------------
|
|
// Invalid char
|
|
// ----------------------------------------------------
|
|
else
|
|
;
|
|
end
|
|
|
|
else
|
|
case fForward^ of
|
|
// ----------------------------------------------------
|
|
// String
|
|
// ----------------------------------------------------
|
|
'"':
|
|
begin
|
|
INC(fForward);
|
|
|
|
while not (fForward^ in ['"',#13,#10]) do
|
|
INC(fForward);
|
|
|
|
if fForward^ = '"' then
|
|
INC(fForward);
|
|
|
|
result := MakeToken( TT_STRING, GetTokenText);
|
|
fStart := fForward;
|
|
end;
|
|
|
|
// ----------------------------------------------------
|
|
// semicolon
|
|
// ----------------------------------------------------
|
|
';':
|
|
begin
|
|
INC(fForward);
|
|
|
|
result := MakeToken( TT_SEMI, ';');
|
|
fStart := fForward;
|
|
end;
|
|
|
|
// ----------------------------------------------------
|
|
// comment
|
|
// ----------------------------------------------------
|
|
'!','/':
|
|
begin
|
|
if fForward^ = '/' then
|
|
begin
|
|
INC(fForward);
|
|
|
|
if fForward^ <> '/' then
|
|
; //raise
|
|
end;
|
|
|
|
INC(fForward);
|
|
|
|
while not (fForward^ in [#13,#10]) do
|
|
INC(fForward);
|
|
|
|
result := MakeToken( TT_COMMENT, GetTokenText);
|
|
fStart := fForward;
|
|
end;
|
|
|
|
// ----------------------------------------------------
|
|
// id
|
|
// ----------------------------------------------------
|
|
'a'..'z','A'..'Z':
|
|
begin
|
|
INC(fForward);
|
|
|
|
while fForward^ in ['a'..'z','A'..'Z'] do
|
|
INC(fForward);
|
|
|
|
ttext := GetTokenText;
|
|
ttype := CheckLiteral( ttext, TT_ID);
|
|
result := MakeToken( ttype, ttext);
|
|
fStart := fForward;
|
|
end;
|
|
|
|
// ----------------------------------------------------
|
|
// number
|
|
// ----------------------------------------------------
|
|
'0'..'9':
|
|
begin
|
|
INC(fForward);
|
|
|
|
while fForward^ in ['0'..'9'] do
|
|
INC(fForward);
|
|
|
|
if fForward^ = '.' then
|
|
begin
|
|
INC(fForward);
|
|
|
|
while fForward^ in ['0'..'9'] do
|
|
INC(fForward)
|
|
end;
|
|
|
|
if fForward^ in ['e','E'] then
|
|
begin
|
|
INC(fForward);
|
|
|
|
if fForward^ in ['+','-'] then
|
|
begin
|
|
INC(fForward);
|
|
|
|
if fForward^ in ['0'..'9'] then
|
|
begin
|
|
INC(fForward);
|
|
|
|
while fForward^ in ['0'..'9'] do
|
|
INC(fForward);
|
|
end
|
|
|
|
else
|
|
// raise
|
|
end
|
|
else
|
|
; // raise
|
|
|
|
end;
|
|
|
|
result := MakeToken( TT_NUMBER, GetTokenText);
|
|
fStart := fForward;
|
|
end;
|
|
|
|
// ----------------------------------------------------
|
|
// HEX start
|
|
// ----------------------------------------------------
|
|
'(':
|
|
begin
|
|
fMode := HEX;
|
|
INC(fForward);
|
|
|
|
result := MakeToken( TT_LPAREN, '');
|
|
fStart := fForward;
|
|
end;
|
|
|
|
// ----------------------------------------------------
|
|
// WS,CR/LF
|
|
// ----------------------------------------------------
|
|
#32, #9: INC(fStart);
|
|
|
|
#13,#10:
|
|
begin
|
|
INC(fStart);
|
|
|
|
while fStart^ in [#13,#10] do
|
|
INC(fStart)
|
|
end;
|
|
|
|
// ----------------------------------------------------
|
|
// EOF
|
|
// ----------------------------------------------------
|
|
#0:
|
|
begin
|
|
result := MakeToken( TT_EOF, '');
|
|
fStart := fForward;
|
|
end;
|
|
|
|
// ----------------------------------------------------
|
|
// invalid
|
|
// ----------------------------------------------------
|
|
else
|
|
begin
|
|
fStart := 0;
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
|
|
if Assigned(result) then
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
end.
|