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

📄 uwparser.pas

📁 Delphi脚本控件
💻 PAS
📖 第 1 页 / 共 4 页
字号:
           end;
       10: begin     // final state 10 represents a read special char
             EAToken := ttSpecialChar;
             Break;
           end;
       12: begin     // final state 12 represents a read comment
             EAToken := ttComment;
             Break;
           end;
       15: begin     // final state 15 represents a read hexadecimal number
             EAToken := ttHexdecimal;
             Break;
           end;
       98: begin     // final state 98 represents a lexical error
             EAToken := ttError;
             Break;
           end;
       99: begin     // final state 99 represents the end of the source stream
             EAToken := ttEOF;
             Break;
           end;
      end;
    end;
  end;
end;

// restart a fomerly broken analysis phase
procedure TWParser.Restart;
var NewToken:  TToken;             // the last read token
    ListToken: TToken;             // copy of the read token that is added to the list of token
    AddToList: Boolean;            // add a new token to the token list (result from user event)
    Stop:      Boolean;            // analysis break (result from user event)
begin
  Eof := false;                         // now end of stream is not yet reached
  Stop := False;                        // initialize abort flag
  NewToken := TToken.Create;            // create the token structure
  repeat                                // repeat until ttEOF Token is read
    ReadToken;                          // read the next token
    NewToken.Token := EAToken;          // save the read token
    if NewToken.Token = ttComment then
      NewToken.SubType := EASubType     // save the read token sub-type
    else
      NewToken.SubType := tsNone;
    NewToken.Text := EAText;            // save the belonging text
    NewToken.Row := EARow;              // save column
    NewToken.Column := EAColumn;        // save row
    NewToken.Position := EAPosition;    // save the position within the stream
    NewToken.Tag := 0;                  // initialize the user information
    // if an identifier is read and the belonging text is a keyword
    // then change the token type into ttKeyword
    if (NewToken.Token=ttIdentifier) and IsKeyword(NewToken.Text) then begin
      NewToken.Token := ttKeyword;
    end;
    // if an identifier is read and no identifiers are allowed then
    // the token type is changed to ttError
    if (NewToken.Token = ttIdentifier) and (not FAllowIdentifier) then begin
      NewToken.Token := ttError;
    end;
    AddToList := true;                  // default is add the new token to the list of tokens
    // if a user defined event is available this event is called before the
    // token is put in the tokenlist
    if Assigned( FOnTokenRead ) then begin
      FOnTokenRead( Self, NewToken, AddToList, Stop );
    end;
    if AddToList then begin
      ListToken := TToken.Create;      // create a new token for the list of tokens
      ListToken.CopyFrom( NewToken );  // copy the contents of the read token
      TokenList.Add( ListToken );      // put the token in the tokenlist
    end;
  until (EAToken = ttEof) or (Stop); // until ttEOF is read or abort flag is set
  NewToken.Free;
end;

// the user defines the additional chars for identifier in a string. this
// string must be converted into a set of char.
procedure TWParser.SetAdditionalChars( Value: string );
var i: Integer;
begin
  FIdentChars := ['a'..'z', 'A'..'Z'];        // first all letters are allowed
  for i := 1 to Length(Value) do begin        // for every char in the string
    FIdentChars := FIdentChars + [Value[i]];  // add the char to the set
  end;
end;

// this method seems to be unnecessary, but it is very important for
// the correct work of TStringList in the object inspector
procedure TWParser.SetKeywords( Value: TStringList );
begin
  FKeywords.Assign( Value );
end;

// the user defines the special char in a string. this string must be converted
// into a set of char. working with a set of char is much easier, but i
// do not want to implement a new property editor for die usage with the
// object inspector
procedure TWParser.SetSpecialChars( Value: string );
var i: Integer;
begin
  FCharacters := [];                          // first the set of char is empty
  for i := 1 to Length(Value) do begin        // for every char in the string
    FCharacters := FCharacters + [Value[i]];  // add the char to the set
  end;
end;

// skip the next count chars from the source stream
procedure TWParser.SkipChars( Count: Integer );
var i:  Integer;
    ch: Char;
begin
  for i := 1 to Count do begin
    ReadCh( ch );
  end;
end;

// the following methods are characterizing the internal state machine

// process a char if the state machine has the state 0
// state 0 is the starting state
procedure TWParser.EASwitch0( ch: Char );
begin
  if Eof then begin    // if the end of source stream is reached
    EAState := 99;     // switch to state 99
  end else begin
    if ch in FIdentChars then begin
      EAState := 1;
      EARow := SourceY;
      EAColumn := SourceX;
      EAPosition := SourceStream.Position;
      ProcessChar;
    end else begin
      case ch of
        '$'       : begin            // if a '$' is available switch to state 16
                      EAState := 16; // and try to read a hex number or a spacial char
                      EARow := SourceY;
                      EAColumn := SourceX;
                      EAPosition := SourceStream.Position;
                      ProcessChar;
                    end;
        '0'       : begin            // if a '0' is read switch to state 13
                      EAState := 13; // and try to read an integer, real or hex number
                      EARow := SourceY;
                      EAColumn := SourceX;
                      EAPosition := SourceStream.Position;
                      ProcessChar;
                    end;
        '1'..'9'  : begin           // if number is read switch to state 3
                      EAState := 3; // and try to read a integer or a floting point number
                      EARow := SourceY;
                      EAColumn := SourceX;
                      EAPosition := SourceStream.Position;
                      ProcessChar;
                    end;
        ''''      : begin           // if the char ' is read switch to state 7
                      EAState := 7; // and try to read a string limited by '
                      EARow := SourceY;
                      EAColumn := SourceX;
                      EAPosition := SourceStream.Position;
                      ReadCh( ch );
                    end;
        '"'       : begin           // if the char " is read switch to state 9
                      EAState := 9; // and try to read a string limited by "
                      EARow := SourceY;
                      EAColumn := SourceX;
                      EAPosition := SourceStream.Position;
                      ReadCh( ch );
                    end;
      else          begin
                      if ch in WhiteSpace then begin // if a white space is read
                      if SourceStream.Position < SourceStream.Size then
                        ReadCh( ch )        // read the next char
                      else
                      begin
                        EAState := 99;
                      end;
                      // if a comment beginning is defined and if the next chars corresend to
                      // the defined comment line begin
                      end
                      else
                      if (Length(FCommentLine) <> 0) and
                                  (EqualStr(LookAHeadStr(Length(FCommentLine)),  FCommentLine))
                      then begin
                        EAState := 11;             // switch to state 11
                        EASubType := tsCommentLine;
                        SkipChars( Length(FCommentLine ) );  // skip the comment line begin
                        EARow := SourceY;          // save row, column and position
                        EAColumn := SourceX;
                        EAPosition := SourceStream.Position;
                      // if a blockcomment beginning is defined and if the next chars corresend to
                      // the defined block comment beginning
                      end
                      else
                      if (Length(FComment1Begin) <> 0) and
                                  (EqualStr(LookAHeadStr(Length(FComment1Begin)),  FComment1Begin))
                      then begin
                        EAState := 18;             // switch to state 18
                        EASubType := tsComment1Block;
                        SkipChars( Length(FComment1Begin ) ); // skip the comment block begin
                        EARow := SourceY;          // save row, column and position
                        EAColumn := SourceX;
                        EAPosition := SourceStream.Position;
                      // if the actual char is a member of the special chars
                      end
                      else
                      if (Length(FComment2Begin) <> 0) and
                                  (EqualStr(LookAHeadStr(Length(FComment2Begin)),  FComment2Begin))
                      then begin
                        EAState := 19;             // switch to state 19
                        EASubType := tsComment2Block;
                        SkipChars( Length(FComment2Begin ) ); // skip the comment block begin
                        EARow := SourceY;          // save row, column and position
                        EAColumn := SourceX;
                        EAPosition := SourceStream.Position;
                      // if the actual char is a member of the special chars
                      end
                      else
                      if ch in FCharacters then begin
                        EAState := 10;             // switch to state 10
                        EARow := SourceY;          // save row, column and position
                        EAColumn := SourceX;
                        EAPosition := SourceStream.Position;
                        ProcessChar;               // process this char
                      // else an illegal char is read and this will cause an error
                      end
                      else
                      begin
                        EAState := 98;             // switch to state 98
                        EARow := SourceY;          // save row, column ans position
                        EAColumn := SourceX;
                        EAPosition := SourceStream.Position;
                        ProcessChar;               // process this char
                      end;
                    end;
      end;
    end;
  end;
end;

// process a char if the state machine has the state 1.
// in this state the state machines tries to read an identifier. an identifier
// consists of a leading char and any following number or char
procedure TWParser.EASwitch1( ch: Char );
begin
  if ch in FIdentChars then begin
    ProcessChar;         // every letter is a part of the identifier
  end else if (FAllowFigures) and (ch in ['0'..'9']) then begin
    ProcessChar;         // if allowed every figures is a part of the identifier
  end else begin
    EAState := 2;        // else switch to final state 2, identifier is complete
  end;
end;

// process a char if the state machine has the state 3.
// in this state a integer or a floating point number is read
procedure TWParser.EASwitch3( ch: Char );
begin
  case ch of
    '0'..'9'  : ProcessChar;    // if a number is read the char is processed
    '.',','   : if LookAheadStr(2)[2] in ['0'..'9'] then begin
                  // if a '.' or a ',' is read and the following char is a figure
                  // the char is processed
                  ProcessChar;  // and the state is switched to state 5 in order
                  EAState := 5; // to read a floating point number
                end else begin
                  EAState := 4; // the state is switched to final state 4 (integer)
                end;
  else          EAState := 4;   // the state is switched to final state 4 (integer)
  end;
end;

// process a char if the state machine has the state 5.
// in this state floating point number is read
procedure TWParser.EASwitch5( ch: Char );

⌨️ 快捷键说明

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