fcl-passrc: parser: check semicolon after if then

git-svn-id: trunk@38061 -
This commit is contained in:
Mattias Gaertner 2018-01-27 16:25:57 +00:00
parent 9240e0c2e6
commit 517e2e3218
2 changed files with 42 additions and 23 deletions

View File

@ -4956,15 +4956,19 @@ var
end; end;
procedure CheckSemicolon; procedure CheckSemicolon;
var
t: TToken;
begin begin
if (CurBlock.Elements.Count>0) and not (GetPrevToken in [tkSemicolon,tkColon]) if (CurBlock.Elements.Count=0) then exit;
and (CurBlock.ClassType<>TPasImplIfElse) then t:=GetPrevToken;
begin if t in [tkSemicolon,tkColon] then
{$IFDEF VerbosePasParser} exit;
writeln('TPasParser.ParseStatement.CheckSemicolon Prev=',GetPrevToken,' Cur=',CurToken,' ',CurBlock.ClassName,' ',CurBlock.Elements.Count,' ',TObject(CurBlock.Elements[0]).ClassName); if (CurBlock.ClassType=TPasImplIfElse) and (t=tkelse) then
{$ENDIF} exit;
ParseExcTokenError('Semicolon'); {$IFDEF VerbosePasParser}
end; writeln('TPasParser.ParseStatement.CheckSemicolon Prev=',GetPrevToken,' Cur=',CurToken,' ',CurBlock.ClassName,' ',CurBlock.Elements.Count,' ',TObject(CurBlock.Elements[0]).ClassName);
{$ENDIF}
ParseExcTokenError('Semicolon');
end; end;
var var
@ -4994,7 +4998,7 @@ begin
while True do while True do
begin begin
NextToken; NextToken;
// WriteLn({$IFDEF VerbosePasParser}i,{$ENDIF}' Token=',CurTokenText); //WriteLn({$IFDEF VerbosePasParser}i,{$ENDIF}' Token=',CurTokenText);
case CurToken of case CurToken of
tkasm: tkasm:
begin begin
@ -5440,7 +5444,7 @@ begin
// assign statement // assign statement
Ak:=TokenToAssignKind(CurToken); Ak:=TokenToAssignKind(CurToken);
NextToken; NextToken;
right:=DoParseExpression(CurBlock); // this may solve TPasImplWhileDo.AddElement BUG right:=DoParseExpression(CurBlock);
El:=TPasImplAssign(CreateElement(TPasImplAssign,'',CurBlock,SrcPos)); El:=TPasImplAssign(CreateElement(TPasImplAssign,'',CurBlock,SrcPos));
left.Parent:=El; left.Parent:=El;
right.Parent:=El; right.Parent:=El;

View File

@ -317,6 +317,7 @@ type
Procedure TestRepeatUntilNonBoolFail; Procedure TestRepeatUntilNonBoolFail;
Procedure TestWhileDoNonBoolFail; Procedure TestWhileDoNonBoolFail;
Procedure TestIfThenNonBoolFail; Procedure TestIfThenNonBoolFail;
Procedure TestIfAssignMissingSemicolonFail;
Procedure TestForLoopVarNonVarFail; Procedure TestForLoopVarNonVarFail;
Procedure TestForLoopStartIncompFail; Procedure TestForLoopStartIncompFail;
Procedure TestForLoopEndIncompFail; Procedure TestForLoopEndIncompFail;
@ -4227,19 +4228,21 @@ end;
procedure TTestResolver.TestStatements; procedure TTestResolver.TestStatements;
begin begin
StartProgram(false); StartProgram(false);
Add('var'); Add([
Add(' v1,v2,v3:longint;'); 'var',
Add('begin'); ' v1,v2,v3:longint;',
Add(' v1:=1;'); 'begin',
Add(' v2:=v1+v1*v1+v1 div v1;'); ' v1:=1;',
Add(' v3:=-v1;'); ' v2:=v1+v1*v1+v1 div v1;',
Add(' repeat'); ' v3:=-v1;',
Add(' v1:=v1+1;'); ' repeat',
Add(' until v1>=5;'); ' v1:=v1+1;',
Add(' while v1>=0 do'); ' until v1>=5;',
Add(' v1:=v1-v2;'); ' while v1>=0 do',
Add(' for v1:=v2 to v3 do v2:=v1;'); ' v1:=v1-v2;',
Add(' if v1<v2 then v3:=v1 else v3:=v2;'); ' for v1:=v2 to v3 do v2:=v1;',
' if v1<v2 then v3:=v1 else v3:=v2;',
'']);
ParseProgram; ParseProgram;
AssertEquals('3 declarations',3,PasProgram.ProgramSection.Declarations.Count); AssertEquals('3 declarations',3,PasProgram.ProgramSection.Declarations.Count);
end; end;
@ -4450,6 +4453,18 @@ begin
CheckResolverException('Boolean expected, but Longint found',nXExpectedButYFound); CheckResolverException('Boolean expected, but Longint found',nXExpectedButYFound);
end; end;
procedure TTestResolver.TestIfAssignMissingSemicolonFail;
begin
StartProgram(false);
Add([
'var',
' v:longint;',
'begin',
' if true then v:=1',
' v:=2']);
CheckParserException('Expected "Semicolon"',nParserExpectTokenError);
end;
procedure TTestResolver.TestForLoopVarNonVarFail; procedure TTestResolver.TestForLoopVarNonVarFail;
begin begin
StartProgram(false); StartProgram(false);