Ignore:
Timestamp:
Sep 8, 2009, 2:01:55 PM (15 years ago)
Author:
george
Message:
  • Přidáno: Analýza páru dalších programových konstrukcí.
  • Přidáno: Pár jednoduchých testovacích příkladů pro překladač.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/DelphiToC/UPascalParser.pas

    r19 r20  
    88
    99type
     10  TPascalParser = class;
     11
    1012  TOnErrorMessage = procedure (Text: string) of object;
     13
     14  TParserCommand = class(TCommand)
     15    procedure Parse(Parser: TPascalParser);
     16  end;
     17
     18  TParserWhileDo = class(TWhileDo)
     19    procedure Parse(Parser: TPascalParser);
     20  end;
     21
     22  TParserExpression = class(TExpression)
     23    procedure Parse(Parser: TPascalParser);
     24  end;
     25
     26
    1127
    1228  TPascalParser = class
     
    3248    procedure ParseModuleProgram(Module: TModule);
    3349    procedure ParseFunction(FunctionList: TFunctionList);
     50    procedure ParseFunctionParameterList(ParameterList: TParameterList);
    3451    procedure ParseVariableList(VariableList: TVariableList);
    3552    procedure ParseVariable(Variable: TVariable);
     
    4057    procedure ParseCommonBlockDefinitions(CommonBlock: TCommonBlock; EndSymbol: string = ';');
    4158    function ParseCommonBlockExpression(CommonBlock: TCommonBlock): TExpression;
    42     procedure ParseCommonBlockProgramCode(CommonBlock: TCommonBlock);
    43     procedure ParseCommonBlockOperation(CommonBlock: TCommonBlock);
     59    function ParseCommand(CommonBlock: TCommonBlock): TCommand;
     60    procedure ParseBeginEnd(CommonBlock: TCommonBlock; Command: TBeginEnd);
     61    procedure ParseIfThenElse(CommonBlock: TCommonBlock; Command: TIfThenElse);
     62    procedure ParseWhileDo(CommonBlock: TCommonBlock; Command: TWhileDo);
    4463    procedure Log(Text: string);
    4564    property OnErrorMessage: TOnErrorMessage read FOnErrorMessage write FOnErrorMessage;
     
    206225
    207226procedure TPascalParser.ParseFunction(FunctionList: TFunctionList);
    208 begin
     227var
     228  Identifiers: TStringList;
     229  NewValueType: TType;
     230  TypeName: string;
     231  VariableName: string;
     232  Variable: TParameter;
     233  I: Integer;
     234begin
     235  Identifiers := TStringList.Create;
    209236  with FunctionList do begin
    210237    with TFunction(Items[Add(TFunction.Create)]) do begin
     238      Parent := FunctionList.Parent;
    211239      Expect('procedure');
    212240      Name := ReadCode;
    213       Expect(';');
    214       ParseCommonBlockDefinitions(Items[Count - 1]);
    215     end;
     241      if NextCode = '(' then begin
     242        Expect('(');
     243        while NextCode <> ')' do begin
     244//    while IsIdentificator(NextCode) do begin
     245          with TParameterList(Parameters) do begin
     246            VariableName := ReadCode;
     247            Variable := Search(VariableName);
     248            if not Assigned(Variable) then begin
     249              Identifiers.Add(VariableName);
     250              while NextCode = ',' do begin
     251                Expect(',');
     252                Identifiers.Add(ReadCode);
     253              end;
     254            end else ErrorMessage('Pøedefinování existující promìnné.');
     255            Expect(':');
     256            TypeName := ReadCode;
     257            NewValueType := Parent.Types.Search(TypeName);
     258            if not Assigned(NewValueType) then ErrorMessage('Typ ' + TypeName + ' nebyl definován.')
     259              else for I := 0 to Identifiers.Count - 1 do
     260                with TParameter(Items[Add(TParameter.Create)]) do begin
     261                  Name := Identifiers[I];
     262                  ValueType := NewValueType;
     263                end;
     264          end;
     265        end;
     266        Expect(')');
     267      end;
     268    end;
     269    Expect(';');
     270    ParseCommonBlockDefinitions(TFunction(Items[Count - 1]));
     271  end;
     272  Identifiers.Destroy;
     273end;
     274
     275procedure TPascalParser.ParseFunctionParameterList(
     276  ParameterList: TParameterList);
     277begin
     278
     279end;
     280
     281procedure TPascalParser.ParseIfThenElse(CommonBlock: TCommonBlock; Command: TIfThenElse);
     282begin
     283  Expect('if');
     284  Expect('than');
     285  if NextCode = 'else' then begin
     286    Expect('else');
    216287  end;
    217288end;
     
    229300      Name := 'main';
    230301      with TType(Types[Types.Add(TType.Create)]) do begin
     302        Name := 'void';
     303        Size := 0;
     304        UsedType := nil;
     305      end;
     306      with TType(Types[Types.Add(TType.Create)]) do begin
    231307        Name := 'byte';
    232308        Size := 1;
    233309        UsedType := nil;
     310      end;
     311      with TFunction(Methods[Methods.Add(TFunction.Create)]) do begin
     312        Name := 'exit';
     313        ResultType := TModule(Modules[0]).Types[0];
    234314      end;
    235315    end;
     
    318398end;
    319399
     400procedure TPascalParser.ParseBeginEnd(CommonBlock: TCommonBlock; Command: TBeginEnd);
     401var
     402  NewCommand: TCommand;
     403begin
     404  with Command do begin
     405    Expect('begin');
     406    while NextCode <> 'end' do begin
     407      NewCommand := ParseCommand(CommonBlock);
     408      if Assigned(NewCommand) then Commands.Add(NewCommand);
     409      //ShowMessage(NextCode);
     410      if NextCode = ';' then ReadCode;     
     411    end;
     412    Expect('end');
     413  end;
     414end;
     415
    320416procedure TPascalParser.ParseCommonBlockDefinitions(CommonBlock: TCommonBlock; EndSymbol: string = ';');
    321417begin
     
    327423      else if NextCode = 'procedure' then ParseFunction(Methods)
    328424      else begin
    329         ParseCommonBlockProgramCode(CommonBlock);
     425        ParseBeginEnd(CommonBlock, Code);
    330426        Break;
    331427      end;
     
    335431end;
    336432
    337 function TPascalParser.ParseCommonBlockExpression(CommonBlock: TCommonBlock): TExpression;
     433function TPascalParser.ParseCommand(CommonBlock: TCommonBlock): TCommand;
     434var
     435  Identifier: string;
     436  Variable: TVariable;
     437  Method: TFunction;
     438  First: TOperation;
     439  Second: TOperation;
     440  StartIndex: Integer;
     441  LoopVariable: TVariable;
     442  IdentName: string;
     443begin
     444  if NextCode = 'begin' then begin
     445    Result := TBeginEnd.Create;
     446    ParseBeginEnd(CommonBlock, TBeginEnd(Result));
     447  end else
     448  if NextCode = 'if' then begin
     449    Result :=  TIfThenElse.Create;
     450    ParseIfThenElse(CommonBlock, TIfThenElse(Result));
     451  end else
     452  if NextCode = 'while' then begin
     453    Result := TWhileDo.Create;
     454    ParseWhileDo(CommonBlock, TWhileDo(Result));
     455  end else
     456  if IsIdentificator(NextCode) then begin
     457    if Assigned(CommonBlock.Variables.Search(NextCode)) then begin
     458      Result := TAssignment.Create;
     459      IdentName := ReadCode;
     460      TAssignment(Result).Target := CommonBlock.Variables.Search(IdentName);
     461      Expect(':=');
     462      TAssignment(Result).Source := ParseCommonBlockExpression(CommonBlock);
     463    end else
     464    if Assigned(CommonBlock.Methods.Search(NextCode)) then begin
     465      Result := TMethodCall.Create;
     466//      ParseMetVariable(TMethodCall(Result).Target);
     467    end;
     468  end;
     469
     470(*    begin
     471      Expect('if');
     472      with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin
     473        Instruction := inConditionalJump;
     474        ExpressionTree := ParseCommonBlockExpression(CommonBlock);
     475        Negative := True;
     476      end;
     477      First := Operations[Operations.Count - 1];
     478      Expect('then');
     479      ParseCommonBlockOperation(CommonBlock);
     480      if NextCode = 'else' then begin
     481        with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin
     482          Instruction := inJump;
     483        end;
     484        Second := Operations[Operations.Count - 1];
     485        First.GotoAddress := Operations.Count;
     486        Expect('else');
     487        ParseCommonBlockOperation(CommonBlock);
     488        Second.GotoAddress := Operations.Count;
     489      end else First.GotoAddress := Operations.Count;
     490    end
     491    else if NextCode = 'repeat' then begin
     492      Expect('repeat');
     493      StartIndex := Operations.Count;
     494      ParseCommonBlockOperation(CommonBlock);
     495      Expect('until');
     496      with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin
     497        Instruction := inConditionalJump;
     498        ExpressionTree := ParseCommonBlockExpression(CommonBlock);
     499        GotoAddress := StartIndex;
     500      end;
     501    end
     502    else if NextCode = 'while' then begin
     503      Expect('while');
     504      with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin
     505        Instruction := inConditionalJump;
     506        ExpressionTree := ParseCommonBlockExpression(CommonBlock);
     507      end;
     508      First := Operations[Operations.Count - 1];
     509      StartIndex := Operations.Count - 1;
     510      Expect('do');
     511      ParseCommonBlockOperation(CommonBlock);
     512      with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin
     513        Instruction := inJump;
     514        GotoAddress := StartIndex;
     515      end;
     516      First.GotoAddress := Operations.Count;
     517    end
     518    else if NextCode = 'for' then begin
     519      Expect('for');
     520      with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin
     521        Instruction := inExpressionEvaluation;
     522        ExpressionTree := ParseCommonBlockExpression(CommonBlock);
     523        if (ExpressionTree.NodeType <> ntOperator) and
     524          (ExpressionTree.OperatorName <> ':=') then ErrorMessage('Expected assigment in for loop');
     525        if TExpression(TExpression(ExpressionTree).SubItems[0]).NodeType <> ntVariable then
     526          ErrorMessage('Index in FOR loop have to be variable');
     527        LoopVaraible := TExpression(TExpression(ExpressionTree).SubItems[0]).Variable;
     528      end;
     529      Expect('to');
     530      with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin
     531        Instruction := inExpressionEvaluation;
     532        ExpressionTree := TExpression.Create;
     533        with ExpressionTree do begin
     534          NodeType := ntOperator;
     535          OperatorName := '=';
     536          SubItems[0] := TExpression.Create;
     537          with TExpression(SubItems[0]) do begin
     538            NodeType := ntVariable;
     539            Variable := LoopVaraible;
     540          end;
     541          SubItems[1] := ParseCommonBlockExpression(CommonBlock);
     542        end;
     543        Negative := True;
     544      end;
     545      First := Operations[Operations.Count - 1];
     546      StartIndex := Operations.Count - 1;
     547      Expect('do');
     548      ParseCommonBlockOperation(CommonBlock);
     549      with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin
     550        Instruction := inExpressionEvaluation;
     551        ExpressionTree := TExpression.Create;
     552        with ExpressionTree do begin
     553          NodeType := ntOperator;
     554          OperatorName := ':=';
     555          SubItems[0] := TExpression.Create;
     556          with TExpression(SubItems[0]) do begin
     557            NodeType := ntVariable;
     558            Variable := LoopVaraible;
     559          end;
     560          SubItems[1] := TExpression.Create;
     561          with TExpression(SubItems[1]) do begin
     562            NodeType := ntOperator;
     563            OperatorName := '+';
     564            SubItems[0] := TExpression.Create;
     565            with TExpression(SubItems[0]) do begin
     566              NodeType := ntVariable;
     567              Variable := LoopVaraible;
     568            end;
     569            SubItems[1] := TExpression.Create;
     570            with TExpression(SubItems[1]) do begin
     571              NodeType := ntConstant;
     572              //SetLength(Value, 1);
     573              //Value[0] := 1;
     574              Value := 1;
     575            end;
     576          end;
     577        end;
     578      end;
     579      with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin
     580        Instruction := inJump;
     581        GotoAddress := StartIndex;
     582      end;
     583      First.GotoAddress := Operations.Count;
     584    end
     585    else begin
     586      with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin
     587        Instruction := inExpressionEvaluation;
     588        ExpressionTree := ParseCommonBlockExpression(CommonBlock);
     589      end;
     590    end;
     591  *)
     592end;
     593
     594procedure TPascalParser.ParseTypeList(TypeList: TTypeList);
     595begin
     596  with TypeList do begin
     597    Expect('type');
     598    while IsIdentificator(NextCode) do
     599      with TType(Items[Add(TType.Create)]) do begin
     600        Parent := TypeList;
     601        ParseType(TType(Items[Count - 1]));
     602      end;
     603  end;
     604end;
     605
     606procedure TPascalParser.ParseVariableList(VariableList: TVariableList);
     607var
     608  Identifiers: TStringList;
     609  NewValueType: TType;
     610  TypeName: string;
     611  VariableName: string;
     612  Variable: TVariable;
     613  I: Integer;
     614begin
     615  Identifiers := TStringList.Create;
     616  with VariableList do begin
     617    Expect('var');
     618    while IsIdentificator(NextCode) do begin
     619      VariableName := ReadCode;
     620      Variable := Search(VariableName);
     621      if not Assigned(Variable) then begin
     622        Identifiers.Add(VariableName);
     623        while NextCode = ',' do begin
     624          Expect(',');
     625          Identifiers.Add(ReadCode);
     626        end;
     627      end else ErrorMessage('Pøedefinování existující promìnné.');
     628      Expect(':');
     629      TypeName := ReadCode;
     630      NewValueType := Parent.Types.Search(TypeName);
     631      if NewValueType = nil then ErrorMessage('Typ ' + TypeName + ' nebyl definován.')
     632        else for I := 0 to Identifiers.Count - 1 do
     633          with TVariable(Items[Add(TVariable.Create)]) do begin
     634            Name := Identifiers[I];
     635            ValueType := NewValueType;
     636          end;
     637      Expect(';');
     638    end;
     639  end;
     640  Identifiers.Destroy;
     641end;
     642
     643procedure TPascalParser.ParseWhileDo(CommonBlock: TCommonBlock; Command: TWhileDo);
     644begin
     645end;
     646
     647procedure TPascalParser.ParseVariable(Variable: TVariable);
     648begin
     649  with Variable do begin
     650    Name := NextCode;
     651    Expect(':=');
     652
     653  end;
     654end;
     655
     656procedure TPascalParser.ParseType(AType: TType);
     657begin
     658  with AType do begin
     659    Name := NextCode;
     660    Expect('=');
     661    UsedType := Parent.Search(NextCode);
     662  end;
     663end;
     664
     665{ TParserWhileDo }
     666
     667procedure TParserWhileDo.Parse(Parser: TPascalParser);
     668begin
     669  with Parser do begin
     670    Expect('while');
     671    TParserExpression(Condition).Parse(Parser);
     672    Expect('do');
     673    TParserCommand(Command).Parse(Parser);
     674  end;
     675end;
     676
     677{ TExpression }
     678
     679procedure TParserExpression.Parse(Parser: TPascalParser);
    338680var
    339681  Identifier: string;
     
    455797end;
    456798
    457 procedure TPascalParser.ParseCommonBlockOperation(CommonBlock: TCommonBlock);
    458 var
    459   Identifier: string;
    460   Variable: TVariable;
    461   Method: TFunction;
    462   First: TOperation;
    463   Second: TOperation;
    464   StartIndex: Integer;
    465   LoopVaraible: TVariable;
    466 begin
    467   with CommonBlock do begin
    468     if NextCode = 'begin' then ParseCommonBlockProgramCode(CommonBlock)
    469     else if NextCode = 'if' then begin
    470       Expect('if');
    471       with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin
    472         Instruction := inConditionalJump;
    473         ExpressionTree := ParseCommonBlockExpression(CommonBlock);
    474         Negative := True;
    475       end;
    476       First := Operations[Operations.Count - 1];
    477       Expect('then');
    478       ParseCommonBlockOperation(CommonBlock);
    479       if NextCode = 'else' then begin
    480         with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin
    481           Instruction := inJump;
    482         end;
    483         Second := Operations[Operations.Count - 1];
    484         First.GotoAddress := Operations.Count;
    485         Expect('else');
    486         ParseCommonBlockOperation(CommonBlock);
    487         Second.GotoAddress := Operations.Count;
    488       end else First.GotoAddress := Operations.Count;
    489     end
    490     else if NextCode = 'repeat' then begin
    491       Expect('repeat');
    492       StartIndex := Operations.Count;
    493       ParseCommonBlockOperation(CommonBlock);
    494       Expect('until');
    495       with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin
    496         Instruction := inConditionalJump;
    497         ExpressionTree := ParseCommonBlockExpression(CommonBlock);
    498         GotoAddress := StartIndex;
    499       end;
    500     end
    501     else if NextCode = 'while' then begin
    502       Expect('while');
    503       with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin
    504         Instruction := inConditionalJump;
    505         ExpressionTree := ParseCommonBlockExpression(CommonBlock);
    506       end;
    507       First := Operations[Operations.Count - 1];
    508       StartIndex := Operations.Count - 1;
    509       Expect('do');
    510       ParseCommonBlockOperation(CommonBlock);
    511       with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin
    512         Instruction := inJump;
    513         GotoAddress := StartIndex;
    514       end;
    515       First.GotoAddress := Operations.Count;
    516     end
    517     else if NextCode = 'for' then begin
    518       Expect('for');
    519       with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin
    520         Instruction := inExpressionEvaluation;
    521         ExpressionTree := ParseCommonBlockExpression(CommonBlock);
    522         if (ExpressionTree.NodeType <> ntOperator) and
    523           (ExpressionTree.OperatorName <> ':=') then ErrorMessage('Expected assigment in for loop');
    524         if TExpression(TExpression(ExpressionTree).SubItems[0]).NodeType <> ntVariable then
    525           ErrorMessage('Index in FOR loop have to be variable');
    526         LoopVaraible := TExpression(TExpression(ExpressionTree).SubItems[0]).Variable;
    527       end;
    528       Expect('to');
    529       with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin
    530         Instruction := inExpressionEvaluation;
    531         ExpressionTree := TExpression.Create;
    532         with ExpressionTree do begin
    533           NodeType := ntOperator;
    534           OperatorName := '=';
    535           SubItems[0] := TExpression.Create;
    536           with TExpression(SubItems[0]) do begin
    537             NodeType := ntVariable;
    538             Variable := LoopVaraible;
    539           end;
    540           SubItems[1] := ParseCommonBlockExpression(CommonBlock);
    541         end;
    542         Negative := True;
    543       end;
    544       First := Operations[Operations.Count - 1];
    545       StartIndex := Operations.Count - 1;
    546       Expect('do');
    547       ParseCommonBlockOperation(CommonBlock);
    548       with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin
    549         Instruction := inExpressionEvaluation;
    550         ExpressionTree := TExpression.Create;
    551         with ExpressionTree do begin
    552           NodeType := ntOperator;
    553           OperatorName := ':=';
    554           SubItems[0] := TExpression.Create;
    555           with TExpression(SubItems[0]) do begin
    556             NodeType := ntVariable;
    557             Variable := LoopVaraible;
    558           end;
    559           SubItems[1] := TExpression.Create;
    560           with TExpression(SubItems[1]) do begin
    561             NodeType := ntOperator;
    562             OperatorName := '+';
    563             SubItems[0] := TExpression.Create;
    564             with TExpression(SubItems[0]) do begin
    565               NodeType := ntVariable;
    566               Variable := LoopVaraible;
    567             end;
    568             SubItems[1] := TExpression.Create;
    569             with TExpression(SubItems[1]) do begin
    570               NodeType := ntConstant;
    571               //SetLength(Value, 1);
    572               //Value[0] := 1;
    573               Value := 1;
    574             end;
    575           end;
    576         end;
    577       end;
    578       with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin
    579         Instruction := inJump;
    580         GotoAddress := StartIndex;
    581       end;
    582       First.GotoAddress := Operations.Count;
    583     end
    584     else begin
    585       with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin
    586         Instruction := inExpressionEvaluation;
    587         ExpressionTree := ParseCommonBlockExpression(CommonBlock);
    588       end;
    589     end;
    590   end;
    591 end;
    592 
    593 procedure TPascalParser.ParseCommonBlockProgramCode(CommonBlock: TCommonBlock);
    594 begin
    595   with CommonBlock do begin
    596     Expect('begin');
    597     while NextCode <> 'end' do begin
    598       ParseCommonBlockOperation(CommonBlock);
    599       Expect(';');
    600     end;
    601     Expect('end');
    602     with TOperation(Operations[Operations.Add(TOperation.Create)]) do begin
    603       Instruction := inReturn;
    604     end;
    605     CheckReferences;
    606   end;
    607 end;
    608 
    609 procedure TPascalParser.ParseTypeList(TypeList: TTypeList);
    610 begin
    611   with TypeList do begin
    612     Expect('type');
    613     while IsIdentificator(NextCode) do
    614       with TType(Items[Add(TType.Create)]) do begin
    615         Parent := TypeList;
    616         ParseType(TType(Items[Count - 1]));
    617       end;
    618   end;
    619 end;
    620 
    621 procedure TPascalParser.ParseVariableList(VariableList: TVariableList);
    622 var
    623   Identifiers: TStringList;
    624   NewValueType: TType;
    625   TypeName: string;
    626   VariableName: string;
    627   Variable: TVariable;
    628   I: Integer;
    629 begin
    630   Identifiers := TStringList.Create;
    631   with VariableList do begin
    632     Expect('var');
    633     while IsIdentificator(NextCode) do begin
    634       VariableName := ReadCode;
    635       Variable := Search(VariableName);
    636       if not Assigned(Variable) then begin
    637         Identifiers.Add(VariableName);
    638         while NextCode = ',' do begin
    639           Expect(',');
    640           Identifiers.Add(ReadCode);
    641         end;
    642       end else ErrorMessage('Pøedefinování existující promìnné.');
    643       Expect(':');
    644       TypeName := ReadCode;
    645       NewValueType := Parent.Types.Search(TypeName);
    646       if NewValueType = nil then ErrorMessage('Typ ' + TypeName + ' nebyl definován.')
    647         else for I := 0 to Identifiers.Count - 1 do
    648           with TVariable(Items[Add(TVariable.Create)]) do begin
    649             Name := Identifiers[I];
    650             ValueType := NewValueType;
    651           end;
    652       Expect(';');
    653     end;
    654   end;
    655   Identifiers.Destroy;
    656 end;
    657 
    658 procedure TPascalParser.ParseVariable(Variable: TVariable);
    659 begin
    660 end;
    661 
    662 procedure TPascalParser.ParseType(AType: TType);
    663 begin
    664   with AType do begin
    665     Name := NextCode;
    666     Expect('=');
    667     UsedType := Parent.Search(NextCode);
    668   end;
    669 end;
    670 
    671799end.
Note: See TracChangeset for help on using the changeset viewer.