Browse Source

passrc: improve parsing code statements. TPasImplCommand replaced by actual simple or assignment. Small fix for the expression parser to handle dot separated identifier

git-svn-id: trunk@15909 -
dmitry 15 năm trước cách đây
mục cha
commit
c3095bf873
2 tập tin đã thay đổi với 63 bổ sung33 xóa
  1. 33 1
      packages/fcl-passrc/src/pastree.pp
  2. 30 32
      packages/fcl-passrc/src/pparser.pp

+ 33 - 1
packages/fcl-passrc/src/pastree.pp

@@ -759,6 +759,8 @@ type
   TPasImplTry = class;
   TPasImplExceptOn = class;
   TPasImplRaise = class;
+  TPasImplAssign = class;
+  TPasImplSimple = class;
   TPasImplLabelMark = class;
 
   { TPasImplBlock }
@@ -784,6 +786,8 @@ type
     function AddExceptOn(const VarName, TypeName: string): TPasImplExceptOn;
     function AddRaise: TPasImplRaise;
     function AddLabelMark(const Id: string): TPasImplLabelMark;
+    function AddAssign(left, right: TPasExpr): TPasImplAssign;
+    function AddSimple(exp: TPasExpr): TPasImplSimple;
     function CloseOnSemicolon: boolean; virtual;
   public
     Elements: TList;    // TPasImplElement objects
@@ -902,6 +906,21 @@ type
     Body: TPasImplElement;
   end;
 
+  { TPasImplAssign }
+
+  TPasImplAssign = class (TPasImplStatement)
+  public
+    left  : TPasExpr;
+    right : TPasExpr;
+  end;
+
+  { TPasImplSimple }
+
+  TPasImplSimple = class (TPasImplStatement)
+  public
+    expr  : TPasExpr;
+  end;
+
   TPasImplTryHandler = class;
   TPasImplTryFinally = class;
   TPasImplTryExcept = class;
@@ -1690,11 +1709,24 @@ end;
 
 function TPasImplBlock.AddLabelMark(const Id: string): TPasImplLabelMark;
 begin
-  Result:=TPasIMplLabelMark.Create('', Self);
+  Result:=TPasImplLabelMark.Create('', Self);
   Result.LabelId:=Id;
   AddElement(Result);
 end;
 
+function TPasImplBlock.AddAssign(left,right:TPasExpr):TPasImplAssign;
+begin
+  Result:=TPasImplAssign.Create('', Self);
+  Result.left:=left;
+  Result.right:=right;
+end;
+
+function TPasImplBlock.AddSimple(exp:TPasExpr):TPasImplSimple;
+begin
+  Result:=TPasImplSimple.Create('', Self);
+  Result.expr:=exp;
+end;
+
 function TPasImplBlock.CloseOnSemicolon: boolean;
 begin
   Result:=false;

+ 30 - 32
packages/fcl-passrc/src/pparser.pp

@@ -933,6 +933,13 @@ begin
           x:=DoParseExpression(AParent);
           if CurToken<>tkBraceClose then Exit;
           NextToken;
+
+          // for the expression like  (TObject(m)).Free;
+          if CurToken = tkDot then begin
+            NextToken;
+            x:=TBinaryExpr.Create(AParent,x, ParseExpIdent(AParent), TokenToExprOp(tkDot));
+          end;
+
         end else begin
           x:=ParseExpIdent(AParent);
         end;
@@ -2669,15 +2676,16 @@ var
 
 var
   Condition: String;
-  Command: String;
   StartValue: String;
   VarName: String;
   EndValue: String;
   Expr: String;
   SubBlock: TPasImplElement;
-  CmdElem: TPasImplCommand;
+  CmdElem: TPasImplElement;
   TypeName: String;
   ForDownTo: Boolean;
+  left: TPasExpr;
+  right: TPasExpr;
 begin
   NewImplElement:=nil;
   CurBlock := Parent;
@@ -2911,42 +2919,32 @@ begin
           ParseExc(SParserSyntaxError);
       end;
     else
-      UngetToken;
-
-      Command:='';
-
-      NextToken;
-      // testing for label mark
-      if CurToken=tkIdentifier then
-      begin
-        Command:=CurTokenText;
-        NextToken;
-        // testing for the goto mark
-        if CurToken=tkColon then
-        begin
-          CurBlock.AddLabelMark(Command);
-        end
-        else
+      left:=DoParseExpression(nil);
+      case CurToken of
+        tkAssign:
         begin
-          Command:='';
-          UngetToken;
+          // assign statement
+          NextToken;
+          right:=ParseExpIdent(Parent);
+          CmdElem:=CurBlock.AddAssign(left, right);
           UngetToken;
         end;
-      end else
+        tkColon:
+        begin
+          if not (left is TPrimitiveExpr) then
+            ParseExc(Format(SParserExpectTokenError, [TokenInfos[tkSemicolon]]));
+          // label mark. todo: check mark identifier in the list of labels
+          CmdElem:=CurBlock.AddLabelMark(TPrimitiveExpr(left).Value);
+          left.Free;
+        end
+      else
+        // simple statement (function call)
+        CmdElem:=CurBlock.AddSimple(left);
         UngetToken;
+      end;
 
-
-      if Command='' then
-      begin
-        // parsing the assignment statement or call expression
-        Command:=ParseCommand;
-        //WriteLn(i,'COMMAND="',Command,'" Token=',CurTokenString);
-        if Command='' then
-          ParseExc(SParserSyntaxError);
-        CmdElem:=CurBlock.AddCommand(Command);
+      if not (CmdElem is TPasImplLabelMark) then
         if NewImplElement=nil then NewImplElement:=CmdElem;
-        if CloseStatement(false) then break;
-      end;
     end;
   end;
 end;