RomanYankovsky / DelphiAST

Abstract syntax tree builder for Delphi
Mozilla Public License 2.0
271 stars 116 forks source link

in procedure X(y: array of const) the `const` part is registered incorrectly. #255

Open JBontes opened 6 years ago

JBontes commented 6 years ago

The following code:

...
  procedure FailFmt(args: array of const);
  procedure FailFmt2(args: array of string);
...

Gets parsed as:

...
            <PARAMETERS line="7" col="20">
              <PARAMETER line="7" col="21">
                <NAME line="7" col="21" name="args"/>
                <TYPE line="7" col="27" type="array">
                  <BOUNDS line="7" col="33"/>
                  <TYPE line="7" col="36" name="const">
                    <IDENTIFIER line="7" col="36" name="const"/>
                  </TYPE>
                </TYPE>
              </PARAMETER>
            </PARAMETERS>
  ...
            <PARAMETERS line="8" col="21">
              <PARAMETER line="8" col="22">
                <NAME line="8" col="22" name="args"/>
                <TYPE line="8" col="28" type="array">
                  <BOUNDS line="8" col="34"/>
                  <TYPE line="8" col="37" name="string"/>
                </TYPE>
              </PARAMETER>
            </PARAMETERS>
  ...

The const keyword is incorrectly tagged as an identifier. It is not. array of const is a special construct that should be treated specially.
See: http://www.dragonkiller.nl/Delphi/delphi2009.html#ArraySubType

I propose the following changes:

procedure TPasSyntaxTreeBuilder.ArrayOfConst;
begin
  //do not fill the name attribute. const is a keyword, not a type.
  //note that the `anType` attribute is empty.
  FStack.Push(ntType).Attribute[anKind]:= AttributeValues[atConst];
  try
    inherited;
  finally
    FStack.Pop;
  end;
end;

procedure TmwSimplePasPar.ArrayType;
begin
  Expected(ptArray);
  ArrayBounds;
  Expected(ptOf);
  ArraySubType;
end;

procedure TmwSimplePasPar.ArrayOfConst;
begin
  Expected(ptConst);
end;

procedure TmwSimplePasPar.ArraySubType;
begin
  case TokenID of
    ptConst: ArrayOfConst;
    else TypeKind;
  end;
end;