Ignore:
Timestamp:
Nov 9, 2009, 3:02:26 PM (15 years ago)
Author:
george
Message:
  • Přidáno: Parser jazyka Void (Pascalovský dialekt).
  • Upraveno: Kontrola syntaxe srovnáváním typů parsovaných tokenů.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/Void/UCompilator.pas

    r9 r10  
    66
    77uses
    8   Classes, SysUtils, UOutputGenerator, UModel;
     8  Classes, SysUtils, UOutputGenerator, UModel, UVoidParser;
    99
    1010type
     
    1616  private
    1717    FOnError: TOnErrorEvent;
    18     ParsePosition: TPoint;
    1918    procedure DoError(Text: string);
    2019  public
    2120    Model: TModel;
    22     SourceCode: TStringList;
     21    SourceCode: TStream;
    2322    Generator: TOutputGenerator;
     23    Parser: TVoidParser;
    2424    procedure Compile;
    25     procedure ProcessLine(Line: string);
     25    procedure Process;
    2626    constructor Create;
    2727    destructor Destroy; override;
    28     function Parse(var Text: string; Separator: string = ' '): string;
    2928    property OnError: TOnErrorEvent read FOnError write FOnError;
    3029  end;
     
    3938begin
    4039  Terminate := False;
    41   if Assigned(FOnError) then FOnError(Text, Terminate, ParsePosition);
     40  if Assigned(FOnError) then FOnError(Text, Terminate, Parser.TokenStartPosition);
    4241  if Terminate then raise Exception.Create('Compilation terminated');
    4342end;
     
    4847begin
    4948  Model.Clear;
     49  SourceCode.Position := 0;
     50  Parser.Open(SourceCode);
    5051
    5152  // Process source lines
    52   for I := 0 to SourceCode.Count - 1 do begin
    53     ParsePosition.Y := I;
    54     ProcessLine(SourceCode[I]);
     53  while SourceCode.Position < SourceCode.Size do begin;
     54    Process;
     55    Parser.ParseNextToken;
    5556  end;
    5657
     
    5859end;
    5960
    60 procedure TCompilator.ProcessLine(Line: string);
     61procedure TCompilator.Process;
    6162var
    6263  CommandName: string;
     
    6465  Variable: TVariable;
    6566  VariableName: string;
     67  Value: string;
    6668begin
    6769  with Model, BeginEnd do begin
    68     CommandName := Parse(Line);
    69     if CommandName = 'Define' then begin
    70       VariableName := Parse(Line);
    71       Variable := FindVariableByName(VariableName);
    72       if Assigned(Variable) then DoError('Variable ' + VariableName + ' redefined')
    73       else begin
    74         Variable := TVariable.Create;
    75         with Variable do begin
    76           Name := VariableName;
    77           VarType := 'string';
     70    if Parser.TokenType = ttIdentifier then begin
     71      CommandName := Parser.TokenValue;
     72      if CommandName = 'Define' then begin
     73        Parser.ParseNextToken;
     74        if Parser.TokenType <> ttWhiteSpace then DoError('Expected white space');
     75        Parser.ParseNextToken;
     76        if Parser.TokenType <> ttIdentifier then DoError('Expected identifier');
     77        VariableName := Parser.TokenValue;
     78        Variable := FindVariableByName(VariableName);
     79        if Assigned(Variable) then DoError('Variable ' + VariableName + ' redefined')
     80        else begin
     81          Variable := TVariable.Create;
     82          with Variable do begin
     83            Name := VariableName;
     84            VarType := 'string';
     85          end;
     86          Variables.Add(Variable);
    7887        end;
    79         Variables.Add(Variable);
     88      end else begin
     89        Command := FindProcedureByName(CommandName);
     90        if Assigned(Command) then begin
     91          with TCommand(Commands[Commands.Add(TCommand.Create)]) do begin
     92            Name := CommandName;
     93            Parser.ParseNextToken;
     94            if (Parser.TokenType = ttSymbol) and (Parser.TokenValue = '(') then begin
     95              Parser.ParseNextToken;
     96              if (Parser.TokenType <> ttString) then DoError('Expected string');
     97              Parameters.Add(Parser.TokenValue);
     98              Parser.ParseNextToken;
     99              if (Parser.TokenType <> ttSymbol) and (Parser.TokenValue = ')') then
     100                DoError('Expected )');
     101            end;
     102          end;
     103        end else begin
     104          Variable := FindVariableByName(CommandName);
     105          if Assigned(Variable) then begin
     106            Parser.ParseNextToken;
     107            if Parser.TokenType <> ttWhiteSpace then DoError('Expected white space');
     108            Parser.ParseNextToken;
     109            if (Parser.TokenType <> ttSymbol) and (Parser.TokenValue = ':=') then
     110              DoError('Expected :=');
     111            Parser.ParseNextToken;
     112            if Parser.TokenType <> ttWhiteSpace then DoError('Expected white space');
     113            Parser.ParseNextToken;
     114            Value := Parser.TokenValue;
     115            if Parser.TokenType = ttIdentifier then begin
     116              Variable := FindVariableByName(CommandName);
     117              if Assigned(Variable) then
     118              with TCommand(Commands[Commands.Add(TCommand.Create)]) do begin
     119                Name := 'Assignment';
     120                Parameters.Add(CommandName);
     121                Parameters.Add(Value);
     122              end else DoError('Undefined variable ' + CommandName);
     123            end else if Parser.TokenType = ttString then begin
     124              with TCommand(Commands[Commands.Add(TCommand.Create)]) do begin
     125                Name := 'Assignment';
     126                Parameters.Add(CommandName);
     127                Parameters.Add(Value);
     128              end;
     129            end else DoError('Expected variable or string')
     130          end else DoError('Unknown command ' + CommandName);
     131        end;
    80132      end;
    81     end else if CommandName = 'Assign' then with TCommand(Commands[Commands.Add(TCommand.Create)]) do begin
    82       VariableName := Parse(Line);
    83       Variable := FindVariableByName(VariableName);
    84       if not Assigned(Variable) then DoError('Undefined variable ' + VariableName)
    85       else begin
    86         Name := 'Assignment';
    87         Parameters.Add(VariableName);
    88         Parameters.Add(Parse(Line));
    89       end;
    90     end else begin
    91       Command := FindProcedureByName(CommandName);
    92       if Assigned(Command) then begin
    93         with TCommand(Commands[Commands.Add(TCommand.Create)]) do begin
    94           Name := CommandName;
    95 
    96         end;
    97       end else DoError('Unknown command ' + CommandName);
    98     end;
     133    end else DoError('Expected identifier');
     134    Parser.ParseNextToken;
     135    if Parser.TokenType <> ttWhiteSpace then DoError('Expected white space');
    99136  end;
    100137end;
     
    102139constructor TCompilator.Create;
    103140begin
    104   SourceCode := TStringList.Create;
     141  SourceCode := TMemoryStream.Create;
    105142  Model := TModel.Create;
     143  Parser := TVoidParser.Create;
    106144end;
    107145
    108146destructor TCompilator.Destroy;
    109 var
    110   I: Integer;
    111147begin
    112148  SourceCode.Destroy;
    113149  Model.Destroy;
     150  Parser.Destroy;
    114151  inherited Destroy;
    115 end;
    116 
    117 function TCompilator.Parse(var Text: string; Separator: string): string;
    118 begin
    119   Text := Trim(Text);
    120   if Pos(Separator, Text) > 0 then begin
    121     Result := Copy(Text, 1, Pos(Separator, Text) - 1);
    122     Delete(Text, 1, Length(Result));
    123   end else begin
    124     Result := Text;
    125     Text := '';
    126   end;
    127   Text := Trim(Text);
    128152end;
    129153
Note: See TracChangeset for help on using the changeset viewer.