Browse Source

* Fix bug #27032, order of operations when parsing a.b[c]

git-svn-id: trunk@33297 -
michael 9 years ago
parent
commit
8f9899e5c4
2 changed files with 54 additions and 9 deletions
  1. 29 9
      packages/fcl-passrc/src/pparser.pp
  2. 25 0
      packages/fcl-passrc/tests/tcexprparser.pas

+ 29 - 9
packages/fcl-passrc/src/pparser.pp

@@ -1320,29 +1320,49 @@ begin
   if x.Kind<>pekSet then NextToken;
   if x.Kind<>pekSet then NextToken;
 
 
   try
   try
-    if x.Kind=pekIdent then begin
+    if x.Kind=pekIdent then
+      begin
+      while CurToken in [tkDot] do
+        begin
+        NextToken;
+        if CurToken=tkIdentifier then
+          begin
+          b:=TBinaryExpr.Create(AParent,x, TPrimitiveExpr.Create(AParent,pekIdent, CurTokenText), eopSubIdent);
+          NextToken;
+          end
+        else
+          begin
+          UngetToken;
+          ParseExc(SParserExpectedIdentifier);
+          end;
+        x:=b;
+        end;
       while CurToken in [tkBraceOpen, tkSquaredBraceOpen, tkCaret] do
       while CurToken in [tkBraceOpen, tkSquaredBraceOpen, tkCaret] do
         case CurToken of
         case CurToken of
-          tkBraceOpen: begin
+          tkBraceOpen:
+            begin
             prm:=ParseParams(AParent,pekFuncParams);
             prm:=ParseParams(AParent,pekFuncParams);
             if not Assigned(prm) then Exit;
             if not Assigned(prm) then Exit;
             prm.Value:=x;
             prm.Value:=x;
             x:=prm;
             x:=prm;
-          end;
-          tkSquaredBraceOpen: begin
+            end;
+          tkSquaredBraceOpen:
+            begin
             prm:=ParseParams(AParent,pekArrayParams);
             prm:=ParseParams(AParent,pekArrayParams);
             if not Assigned(prm) then Exit;
             if not Assigned(prm) then Exit;
             prm.Value:=x;
             prm.Value:=x;
             x:=prm;
             x:=prm;
-          end;
-          tkCaret: begin
+            end;
+          tkCaret:
+            begin
             u:=TUnaryExpr.Create(AParent,x, TokenToExprOp(CurToken));
             u:=TUnaryExpr.Create(AParent,x, TokenToExprOp(CurToken));
             x:=u;
             x:=u;
             NextToken;
             NextToken;
-          end;
+            end;
         end;
         end;
-
-      if CurToken in [tkDot, tkas] then begin
+      // Needed for TSDOBaseDataObjectClass(Self.ClassType).Create
+      if CurToken in [tkdot,tkas] then
+        begin
         optk:=CurToken;
         optk:=CurToken;
         NextToken;
         NextToken;
         b:=TBinaryExpr.Create(AParent,x, ParseExpIdent(AParent), TokenToExprOp(optk));
         b:=TBinaryExpr.Create(AParent,x, ParseExpIdent(AParent), TokenToExprOp(optk));

+ 25 - 0
packages/fcl-passrc/tests/tcexprparser.pas

@@ -86,6 +86,7 @@ type
     Procedure TestBinaryLargerThanEqual;
     Procedure TestBinaryLargerThanEqual;
     procedure TestBinaryFullIdent;
     procedure TestBinaryFullIdent;
     Procedure TestArrayElement;
     Procedure TestArrayElement;
+    Procedure TestArrayElementrecord;
     Procedure TestArrayElement2Dims;
     Procedure TestArrayElement2Dims;
     Procedure TestFunctionCall;
     Procedure TestFunctionCall;
     Procedure TestFunctionCall2args;
     Procedure TestFunctionCall2args;
@@ -119,6 +120,7 @@ type
     Procedure TestPrecedenceMultiplyDiv;
     Procedure TestPrecedenceMultiplyDiv;
     Procedure TestPrecedenceDivMultiply;
     Procedure TestPrecedenceDivMultiply;
     Procedure TestTypeCast;
     Procedure TestTypeCast;
+    procedure TestTypeCast2;
     Procedure TestCreate;
     Procedure TestCreate;
   end;
   end;
 
 
@@ -200,6 +202,23 @@ begin
   AssertExpression('Simple identifier',p.params[0],pekNumber,'1');
   AssertExpression('Simple identifier',p.params[0],pekNumber,'1');
 end;
 end;
 
 
+procedure TTestExpressions.TestArrayElementrecord;
+
+Var
+  P : TParamsExpr;
+  B : TBinaryExpr;
+begin
+  DeclareVar('record a : array[1..2] of integer; end ','b');
+  ParseExpression('b.a[1]');
+  P:=TParamsExpr(AssertExpression('Simple identifier',theExpr,pekArrayParams,TParamsExpr));
+  B:=AssertExpression('Name of array',P.Value,pekBinary,TBInaryExpr) as TBInaryExpr;
+  AssertEquals('name is Subident',eopSubIdent,B.Opcode);
+  AssertExpression('Name of array',B.Left,pekIdent,'b');
+  AssertExpression('Name of array',B.Right,pekIdent,'a');
+  AssertEquals('One dimension',1,Length(p.params));
+  AssertExpression('Simple identifier',p.params[0],pekNumber,'1');
+end;
+
 procedure TTestExpressions.TestArrayElement2Dims;
 procedure TTestExpressions.TestArrayElement2Dims;
 Var
 Var
   P : TParamsExpr;
   P : TParamsExpr;
@@ -471,6 +490,12 @@ begin
   ParseExpression('TSDOBaseDataObjectClass(Self.ClassType).Create');
   ParseExpression('TSDOBaseDataObjectClass(Self.ClassType).Create');
 end;
 end;
 
 
+procedure TTestExpressions.TestTypeCast2;
+begin
+  DeclareVar('TSDOBaseDataObjectClass');
+  ParseExpression('TSDOBaseDataObjectClass(Self.ClassType).Create.D');
+end;
+
 procedure TTestExpressions.TestCreate;
 procedure TTestExpressions.TestCreate;
 begin
 begin
   DeclareVar('ESDOSerializationException');
   DeclareVar('ESDOSerializationException');