|
@@ -350,6 +350,7 @@ type
|
|
|
procedure CheckTokens(tk: TTokens);
|
|
|
procedure ExpectToken(tk: TToken);
|
|
|
procedure ExpectTokens(tk: TTokens);
|
|
|
+ function GetPrevToken: TToken;
|
|
|
function ExpectIdentifier: String;
|
|
|
Function CurTokenIsIdentifier(Const S : String) : Boolean;
|
|
|
// Expression parsing
|
|
@@ -1047,6 +1048,22 @@ begin
|
|
|
CheckTokens(tk);
|
|
|
end;
|
|
|
|
|
|
+function TPasParser.GetPrevToken: TToken;
|
|
|
+var
|
|
|
+ i: Integer;
|
|
|
+ P: PTokenRec;
|
|
|
+begin
|
|
|
+ if FTokenRingStart = FTokenRingEnd then
|
|
|
+ Result:=tkEOF;
|
|
|
+ i:=FTokenRingCur;
|
|
|
+ if i>0 then
|
|
|
+ dec(i)
|
|
|
+ else
|
|
|
+ i:=High(FTokenRing);
|
|
|
+ P:=@FTokenRing[i];
|
|
|
+ Result := P^.Token;
|
|
|
+end;
|
|
|
+
|
|
|
function TPasParser.ExpectIdentifier: String;
|
|
|
begin
|
|
|
ExpectToken(tkIdentifier);
|
|
@@ -1058,7 +1075,6 @@ begin
|
|
|
Result:=(Curtoken=tkIdentifier) and (CompareText(S,CurtokenText)=0);
|
|
|
end;
|
|
|
|
|
|
-
|
|
|
function TPasParser.IsCurTokenHint(out AHint: TPasMemberHint): Boolean;
|
|
|
begin
|
|
|
Result:=CurToken=tklibrary;
|
|
@@ -2811,7 +2827,6 @@ begin
|
|
|
ExpectToken(tkend);
|
|
|
end;
|
|
|
until false;
|
|
|
- UngetToken;
|
|
|
end;
|
|
|
|
|
|
function TPasParser.GetProcTypeFromToken(tk: TToken; IsClass: Boolean
|
|
@@ -4742,9 +4757,28 @@ var
|
|
|
if NewImplElement=nil then NewImplElement:=CurBlock;
|
|
|
end;
|
|
|
|
|
|
+ procedure CheckSemicolon;
|
|
|
+ begin
|
|
|
+ if (CurBlock.Elements.Count>0) and not (GetPrevToken in [tkSemicolon,tkColon])
|
|
|
+ and (CurBlock.ClassType<>TPasImplIfElse) then
|
|
|
+ begin
|
|
|
+ writeln('TPasParser.ParseStatement.CheckSemicolon Prev=',GetPrevToken,' Cur=',CurToken,' ',CurBlock.ClassName,' ',CurBlock.Elements.Count,' ',TObject(CurBlock.Elements[0]).ClassName);
|
|
|
+ ParseExcTokenError('Semicolon');
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
var
|
|
|
- SubBlock: TPasImplElement;
|
|
|
CmdElem: TPasImplElement;
|
|
|
+
|
|
|
+ procedure AddStatement(El: TPasImplElement);
|
|
|
+ begin
|
|
|
+ CurBlock.AddElement(El);
|
|
|
+ CmdElem:=El;
|
|
|
+ UngetToken;
|
|
|
+ end;
|
|
|
+
|
|
|
+var
|
|
|
+ SubBlock: TPasImplElement;
|
|
|
left, right: TPasExpr;
|
|
|
El : TPasImplElement;
|
|
|
ak : TAssignKind;
|
|
@@ -4764,6 +4798,7 @@ begin
|
|
|
case CurToken of
|
|
|
tkasm:
|
|
|
begin
|
|
|
+ CheckSemicolon;
|
|
|
El:=TPasImplElement(CreateElement(TPasImplAsmStatement,'',CurBlock));
|
|
|
ParseAsmBlock(TPasImplAsmStatement(El));
|
|
|
CurBlock.AddElement(El);
|
|
@@ -4773,16 +4808,19 @@ begin
|
|
|
end;
|
|
|
tkbegin:
|
|
|
begin
|
|
|
+ CheckSemicolon;
|
|
|
El:=TPasImplElement(CreateElement(TPasImplBeginBlock,'',CurBlock));
|
|
|
CreateBlock(TPasImplBeginBlock(El));
|
|
|
end;
|
|
|
tkrepeat:
|
|
|
begin
|
|
|
+ CheckSemicolon;
|
|
|
El:=TPasImplRepeatUntil(CreateElement(TPasImplRepeatUntil,'',CurBlock));
|
|
|
CreateBlock(TPasImplRepeatUntil(El));
|
|
|
end;
|
|
|
tkIf:
|
|
|
begin
|
|
|
+ CheckSemicolon;
|
|
|
NextToken;
|
|
|
Left:=DoParseExpression(CurBlock);
|
|
|
UngetToken;
|
|
@@ -4853,6 +4891,7 @@ begin
|
|
|
tkwhile:
|
|
|
begin
|
|
|
// while Condition do
|
|
|
+ CheckSemicolon;
|
|
|
NextToken;
|
|
|
left:=DoParseExpression(CurBlock);
|
|
|
UngetToken;
|
|
@@ -4864,14 +4903,16 @@ begin
|
|
|
end;
|
|
|
tkgoto:
|
|
|
begin
|
|
|
- NextToken;
|
|
|
- curblock.AddCommand('goto '+curtokenstring);
|
|
|
- // expecttoken(tkSemiColon);
|
|
|
+ CheckSemicolon;
|
|
|
+ NextToken;
|
|
|
+ CurBlock.AddCommand('goto '+curtokenstring);
|
|
|
+ // expecttoken(tkSemiColon);
|
|
|
end;
|
|
|
tkfor:
|
|
|
begin
|
|
|
// for VarName := StartValue to EndValue do
|
|
|
// for VarName in Expression do
|
|
|
+ CheckSemicolon;
|
|
|
El:=TPasImplForLoop(CreateElement(TPasImplForLoop,'',CurBlock));
|
|
|
ok:=false;
|
|
|
Try
|
|
@@ -4928,6 +4969,7 @@ begin
|
|
|
begin
|
|
|
// with Expr do
|
|
|
// with Expr, Expr do
|
|
|
+ CheckSemicolon;
|
|
|
SrcPos:=CurSourcePos;
|
|
|
NextToken;
|
|
|
Left:=DoParseExpression(CurBlock);
|
|
@@ -4948,6 +4990,7 @@ begin
|
|
|
end;
|
|
|
tkcase:
|
|
|
begin
|
|
|
+ CheckSemicolon;
|
|
|
NextToken;
|
|
|
Left:=DoParseExpression(CurBlock);
|
|
|
UngetToken;
|
|
@@ -5025,6 +5068,7 @@ begin
|
|
|
end;
|
|
|
tktry:
|
|
|
begin
|
|
|
+ CheckSemicolon;
|
|
|
El:=TPasImplTry(CreateElement(TPasImplTry,'',CurBlock));
|
|
|
CreateBlock(TPasImplTry(El));
|
|
|
end;
|
|
@@ -5061,6 +5105,7 @@ begin
|
|
|
end;
|
|
|
tkraise:
|
|
|
begin
|
|
|
+ CheckSemicolon;
|
|
|
El:=TPasImplRaise(CreateElement(TPasImplRaise,'',CurBlock));
|
|
|
CreateBlock(TPasImplRaise(El));
|
|
|
NextToken;
|
|
@@ -5105,7 +5150,11 @@ begin
|
|
|
tkSemiColon:
|
|
|
if CloseStatement(true) then break;
|
|
|
tkFinalization:
|
|
|
- if CloseStatement(true) then break;
|
|
|
+ if CloseStatement(true) then
|
|
|
+ begin
|
|
|
+ UngetToken;
|
|
|
+ break;
|
|
|
+ end;
|
|
|
tkuntil:
|
|
|
begin
|
|
|
if CloseStatement(true) then
|
|
@@ -5131,6 +5180,7 @@ begin
|
|
|
// Do not check this here:
|
|
|
// if (CurToken=tkAt) and not (msDelphi in CurrentModeswitches) then
|
|
|
// ParseExc;
|
|
|
+ CheckSemicolon;
|
|
|
|
|
|
// On is usable as an identifier
|
|
|
if lowerCase(CurTokenText)='on' then
|
|
@@ -5189,9 +5239,7 @@ begin
|
|
|
TPasImplAssign(El).left:=Left;
|
|
|
TPasImplAssign(El).right:=Right;
|
|
|
TPasImplAssign(El).Kind:=ak;
|
|
|
- CurBlock.AddElement(El);
|
|
|
- CmdElem:=TPasImplAssign(El);
|
|
|
- UngetToken;
|
|
|
+ AddStatement(El);
|
|
|
end;
|
|
|
tkColon:
|
|
|
begin
|
|
@@ -5208,9 +5256,7 @@ begin
|
|
|
// simple statement (function call)
|
|
|
El:=TPasImplSimple(CreateElement(TPasImplSimple,'',CurBlock));
|
|
|
TPasImplSimple(El).expr:=Left;
|
|
|
- CurBlock.AddElement(El);
|
|
|
- CmdElem:=TPasImplSimple(El);
|
|
|
- UngetToken;
|
|
|
+ AddStatement(El);
|
|
|
end;
|
|
|
|
|
|
if not (CmdElem is TPasImplLabelMark) then
|