Browse Source

fcl-passrc: fixed parsing (@i)[j]

git-svn-id: trunk@38818 -
Mattias Gaertner 7 years ago
parent
commit
6a95122007
1 changed files with 30 additions and 22 deletions
  1. 30 22
      packages/fcl-passrc/src/pparser.pp

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

@@ -2263,7 +2263,8 @@ begin
   end;
 end;
 
-function TPasParser.DoParseExpression(AParent : TPaselement;InitExpr: TPasExpr; AllowEqual : Boolean = True): TPasExpr;
+function TPasParser.DoParseExpression(AParent: TPasElement; InitExpr: TPasExpr;
+  AllowEqual : Boolean = True): TPasExpr;
 type
   TOpStackItem = record
     Token: TToken;
@@ -2281,7 +2282,7 @@ var
   NotBinary : Boolean;
 
 const
-  PrefixSym = [tkPlus, tkMinus, tknot, tkAt, tkAtAt]; // + - not @
+  PrefixSym = [tkPlus, tkMinus, tknot, tkAt, tkAtAt]; // + - not @ @@
   BinaryOP  = [tkMul, tkDivision, tkdiv, tkmod,  tkDotDot,
                tkand, tkShl,tkShr, tkas, tkPower,
                tkPlus, tkMinus, tkor, tkxor, tkSymmetricalDifference,
@@ -2348,6 +2349,7 @@ const
 Var
   AllowedBinaryOps : Set of TToken;
   SrcPos: TPasSourcePos;
+  ArrParams: TParamsExpr;
 
 begin
   AllowedBinaryOps:=BinaryOP;
@@ -2364,19 +2366,8 @@ begin
       PrefixCnt:=0;
       if not Assigned(InitExpr) then
         begin
-        // the first part of the expression has been parsed externally.
-        // this is used by Constant Expression parser (CEP) parsing only,
-        // whenever it makes a false assuming on constant expression type.
-        // i.e: SI_PAD_SIZE = ((128/sizeof(longint)) - 3);
-        //
-        // CEP assumes that it's array or record, because the expression
-        // starts with "(". After the first part is parsed, the CEP meets "-"
-        // that assures, it's not an array expression. The CEP should give the
-        // first part back to the expression parser, to get the correct
-        // token tree according to the operations priority.
-        //
-        // quite ugly. type information is required for CEP to work clean
 
+        // parse prefix operators
         while CurToken in PrefixSym do
           begin
           PushOper(CurToken);
@@ -2388,6 +2379,8 @@ begin
           begin
           NextToken;
           x:=DoParseExpression(AParent);
+          if not Assigned(x) then
+            ParseExcSyntaxError;
           if (CurToken<>tkBraceClose) then
             begin
             x.Release;
@@ -2395,18 +2388,21 @@ begin
             end;
           NextToken;
           // for expressions like (ppdouble)^^;
-          while (x<>Nil) and (CurToken=tkCaret) do
+          while (CurToken=tkCaret) do
             begin
             x:=CreateUnaryExpr(AParent,x, TokenToExprOp(tkCaret));
             NextToken;
             end;
           // for expressions like (PChar(a)+10)[0];
-          if (x<>Nil) and (CurToken=tkSquaredBraceOpen) then
+          if (CurToken=tkSquaredBraceOpen) then
             begin
-            x:=ParseParams(x,pekArrayParams,False);
+            ArrParams:=ParseParams(AParent,pekArrayParams,False);
+            ArrParams.Value:=x;
+            x.Parent:=ArrParams;
+            x:=ArrParams;
             end;
           // for expressions like (TObject(m)).Free;
-          if (x<>Nil) and (CurToken=tkDot) then
+          if (CurToken=tkDot) then
             begin
             NextToken;
             x:=CreateBinaryExpr(AParent,x, ParseExpIdent(AParent), TokenToExprOp(tkDot));
@@ -2415,9 +2411,9 @@ begin
         else
           begin
           x:=ParseExpIdent(AParent);
+          if not Assigned(x) then
+            ParseExcSyntaxError;
           end;
-        if not Assigned(x) then
-          ParseExcSyntaxError;
         ExpStack.Add(x);
 
         for i:=1 to PrefixCnt do
@@ -2436,12 +2432,24 @@ begin
         end
       else
         begin
+        // the first part of the expression has been parsed externally.
+        // this is used by Constant Expression parser (CEP) parsing only,
+        // whenever it makes a false assuming on constant expression type.
+        // i.e: SI_PAD_SIZE = ((128/sizeof(longint)) - 3);
+        //
+        // CEP assumes that it's array or record, because the expression
+        // starts with "(". After the first part is parsed, the CEP meets "-"
+        // that assures, it's not an array expression. The CEP should give the
+        // first part back to the expression parser, to get the correct
+        // token tree according to the operations priority.
+        //
+        // quite ugly. type information is required for CEP to work clean
         ExpStack.Add(InitExpr);
         InitExpr:=nil;
         end;
       if (CurToken in AllowedBinaryOPs) then
         begin
-        // Adjusting order of the operations
+        // process operators of higher precedence than next operator
         NotBinary:=False;
         TempOp:=PeekOper;
         while (OpStackTop>=0) and (OpLevel(TempOp)>=OpLevel(CurToken)) do begin
@@ -2458,7 +2466,7 @@ begin
 
     while OpStackTop>=0 do PopAndPushOperator;
 
-    // only 1 expression should be on the OpStack, at the end of the correct expression
+    // only 1 expression should be left on the OpStack
     if ExpStack.Count<>1 then
       ParseExcSyntaxError;
     if ExpStack.Count=1 then