mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-13 14:09:16 +02:00
codetools: parsing if-then-else in TPascalParserTool.ReadTilBlockEnd, bug #23542
git-svn-id: trunk@39656 -
This commit is contained in:
parent
9862bf3af8
commit
17337ba49d
@ -1361,6 +1361,7 @@ begin
|
|||||||
Add('TRY' ,{$ifdef FPC}@{$endif}AllwaysTrue);
|
Add('TRY' ,{$ifdef FPC}@{$endif}AllwaysTrue);
|
||||||
Add('ASM' ,{$ifdef FPC}@{$endif}AllwaysTrue);
|
Add('ASM' ,{$ifdef FPC}@{$endif}AllwaysTrue);
|
||||||
Add('CASE' ,{$ifdef FPC}@{$endif}AllwaysTrue);
|
Add('CASE' ,{$ifdef FPC}@{$endif}AllwaysTrue);
|
||||||
|
Add('IF' ,{$ifdef FPC}@{$endif}AllwaysTrue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
UnexpectedKeyWordInBeginBlock:=TKeyWordFunctionList.Create('UnexpectedKeyWordInBeginBlock');
|
UnexpectedKeyWordInBeginBlock:=TKeyWordFunctionList.Create('UnexpectedKeyWordInBeginBlock');
|
||||||
|
@ -283,9 +283,10 @@ implementation
|
|||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
TEndBlockType = (ebtBegin, ebtAsm, ebtTry, ebtCase, ebtRepeat, ebtRecord,
|
TEndBlockType = (ebtBegin, ebtAsm, ebtTry, ebtCase, ebtRepeat, ebtIf,
|
||||||
ebtClass, ebtObject);
|
ebtRecord, ebtClass, ebtObject);
|
||||||
TTryType = (ttNone, ttFinally, ttExcept);
|
TTryType = (ttNone, ttFinally, ttExcept);
|
||||||
|
TIfType = (itNone, itThen, itElse);
|
||||||
|
|
||||||
function ProcHeadAttributesToStr(Attr: TProcHeadAttributes): string;
|
function ProcHeadAttributesToStr(Attr: TProcHeadAttributes): string;
|
||||||
var
|
var
|
||||||
@ -2649,11 +2650,12 @@ end;
|
|||||||
|
|
||||||
function TPascalParserTool.ReadTilBlockEnd(
|
function TPascalParserTool.ReadTilBlockEnd(
|
||||||
StopOnBlockMiddlePart, CreateNodes: boolean): boolean;
|
StopOnBlockMiddlePart, CreateNodes: boolean): boolean;
|
||||||
// after reading cursor will be on the keyword ending the block (e.g. 'end')
|
// after reading cursor will be on the atom ending the block (e.g. 'end', 'until', or ';')
|
||||||
var BlockType: TEndBlockType;
|
var BlockType: TEndBlockType;
|
||||||
TryType: TTryType;
|
TryType: TTryType;
|
||||||
BlockStartPos: integer;
|
BlockStartPos: integer;
|
||||||
Desc: TCodeTreeNodeDesc;
|
Desc: TCodeTreeNodeDesc;
|
||||||
|
IfType: TIfType;
|
||||||
|
|
||||||
procedure SaveRaiseExceptionWithBlockStartHint(const AMessage: string);
|
procedure SaveRaiseExceptionWithBlockStartHint(const AMessage: string);
|
||||||
var CaretXY: TCodeXYPosition;
|
var CaretXY: TCodeXYPosition;
|
||||||
@ -2698,7 +2700,9 @@ var BlockType: TEndBlockType;
|
|||||||
begin
|
begin
|
||||||
Result:=true;
|
Result:=true;
|
||||||
TryType:=ttNone;
|
TryType:=ttNone;
|
||||||
|
IfType:=itNone;
|
||||||
Desc:=ctnNone;
|
Desc:=ctnNone;
|
||||||
|
//debugln(['TPascalParserTool.ReadTilBlockEnd START ',GetAtom]);
|
||||||
if UpAtomIs('BEGIN') then begin
|
if UpAtomIs('BEGIN') then begin
|
||||||
BlockType:=ebtBegin;
|
BlockType:=ebtBegin;
|
||||||
Desc:=ctnBeginBlock;
|
Desc:=ctnBeginBlock;
|
||||||
@ -2706,6 +2710,8 @@ begin
|
|||||||
BlockType:=ebtRepeat
|
BlockType:=ebtRepeat
|
||||||
else if UpAtomIs('TRY') then
|
else if UpAtomIs('TRY') then
|
||||||
BlockType:=ebtTry
|
BlockType:=ebtTry
|
||||||
|
else if UpAtomIs('IF') then
|
||||||
|
BlockType:=ebtIf
|
||||||
else if UpAtomIs('CASE') then
|
else if UpAtomIs('CASE') then
|
||||||
BlockType:=ebtCase
|
BlockType:=ebtCase
|
||||||
else if UpAtomIs('ASM') then
|
else if UpAtomIs('ASM') then
|
||||||
@ -2724,18 +2730,20 @@ begin
|
|||||||
BlockStartPos:=CurPos.StartPos;
|
BlockStartPos:=CurPos.StartPos;
|
||||||
repeat
|
repeat
|
||||||
ReadNextAtom;
|
ReadNextAtom;
|
||||||
|
//debugln(['TPascalParserTool.ReadTilBlockEnd next=',GetAtom]);
|
||||||
if (CurPos.StartPos>SrcLen) then
|
if (CurPos.StartPos>SrcLen) then
|
||||||
SaveRaiseExceptionWithBlockStartHint(ctsUnexpectedEndOfSource);
|
SaveRaiseExceptionWithBlockStartHint(ctsUnexpectedEndOfSource);
|
||||||
|
|
||||||
if not (CurPos.Flag in AllCommonAtomWords) then continue;
|
|
||||||
|
|
||||||
if (CurPos.Flag=cafEND) then begin
|
if (CurPos.Flag=cafEND) then begin
|
||||||
|
// end
|
||||||
if (BlockType<>ebtAsm) or (CurPos.StartPos=1) or (Src[CurPos.StartPos-1]<>'@')
|
if (BlockType<>ebtAsm) or (CurPos.StartPos=1) or (Src[CurPos.StartPos-1]<>'@')
|
||||||
then begin
|
then begin
|
||||||
if BlockType=ebtRepeat then
|
if BlockType=ebtRepeat then
|
||||||
RaiseStrExpectedWithBlockStartHint('"until"');
|
RaiseStrExpectedWithBlockStartHint('"until"');
|
||||||
if (BlockType=ebtTry) and (TryType=ttNone) then
|
if (BlockType=ebtTry) and (TryType=ttNone) then
|
||||||
RaiseStrExpectedWithBlockStartHint('"finally"');
|
RaiseStrExpectedWithBlockStartHint('"finally"');
|
||||||
|
if (BlockType=ebtIf) and (IfType=itNone) then
|
||||||
|
RaiseStrExpectedWithBlockStartHint('"then"');
|
||||||
if Desc<>ctnNone then begin
|
if Desc<>ctnNone then begin
|
||||||
CurNode.EndPos:=CurPos.EndPos;
|
CurNode.EndPos:=CurPos.EndPos;
|
||||||
EndChildNode;
|
EndChildNode;
|
||||||
@ -2747,12 +2755,24 @@ begin
|
|||||||
UndoReadNextAtom;
|
UndoReadNextAtom;
|
||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
end else if EndKeyWordFuncList.DoIdentifier(@Src[CurPos.StartPos])
|
end else if CurPos.Flag=cafSemicolon then begin
|
||||||
or UpAtomIs('REPEAT') then
|
// ;
|
||||||
begin
|
if BlockType=ebtIf then begin
|
||||||
|
if (IfType=itNone) then
|
||||||
|
RaiseStrExpectedWithBlockStartHint('"then"');
|
||||||
|
if Desc<>ctnNone then begin
|
||||||
|
CurNode.EndPos:=CurPos.EndPos;
|
||||||
|
EndChildNode;
|
||||||
|
end;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end else if CurPos.Flag<>cafWord then begin
|
||||||
|
continue;
|
||||||
|
end else if BlockStatementStartKeyWordFuncList.DoIdentifier(@Src[CurPos.StartPos])
|
||||||
|
then begin
|
||||||
if BlockType=ebtAsm then
|
if BlockType=ebtAsm then
|
||||||
SaveRaiseUnexpectedKeyWordInAsmBlock;
|
SaveRaiseUnexpectedKeyWordInAsmBlock;
|
||||||
if (BlockType<>ebtRecord) or (not UpAtomIs('CASE')) then
|
if (BlockType<>ebtRecord) then
|
||||||
ReadTilBlockEnd(false,CreateNodes);
|
ReadTilBlockEnd(false,CreateNodes);
|
||||||
end else if UpAtomIs('UNTIL') then begin
|
end else if UpAtomIs('UNTIL') then begin
|
||||||
if BlockType<>ebtRepeat then
|
if BlockType<>ebtRepeat then
|
||||||
@ -2774,6 +2794,19 @@ begin
|
|||||||
TryType:=ttExcept;
|
TryType:=ttExcept;
|
||||||
end else
|
end else
|
||||||
RaiseStrExpectedWithBlockStartHint('"end"');
|
RaiseStrExpectedWithBlockStartHint('"end"');
|
||||||
|
end else if UpAtomIs('THEN') then begin
|
||||||
|
if (BlockType=ebtIf) and (IfType=itNone) then begin
|
||||||
|
debugln(['TPascalParserTool.ReadTilBlockEnd BBB1']);
|
||||||
|
if StopOnBlockMiddlePart then break;
|
||||||
|
IfType:=itThen;
|
||||||
|
end else
|
||||||
|
RaiseStrExpectedWithBlockStartHint('"if"');
|
||||||
|
end else if UpAtomIs('ELSE') then begin
|
||||||
|
if (BlockType=ebtIf) and (IfType=itThen) then begin
|
||||||
|
if StopOnBlockMiddlePart then break;
|
||||||
|
IfType:=itElse;
|
||||||
|
end else
|
||||||
|
RaiseStrExpectedWithBlockStartHint('"if"');
|
||||||
end else if CreateNodes and UpAtomIs('WITH') then begin
|
end else if CreateNodes and UpAtomIs('WITH') then begin
|
||||||
ReadWithStatement(true,CreateNodes);
|
ReadWithStatement(true,CreateNodes);
|
||||||
end else if CreateNodes and UpAtomIs('ON') and (BlockType=ebtTry)
|
end else if CreateNodes and UpAtomIs('ON') and (BlockType=ebtTry)
|
||||||
@ -2783,7 +2816,7 @@ begin
|
|||||||
// check for unexpected keywords
|
// check for unexpected keywords
|
||||||
case BlockType of
|
case BlockType of
|
||||||
|
|
||||||
ebtBegin,ebtTry,ebtCase,ebtRepeat:
|
ebtBegin,ebtTry,ebtIf,ebtCase,ebtRepeat:
|
||||||
if UnexpectedKeyWordInBeginBlock.DoIdentifier(@Src[CurPos.StartPos]) then
|
if UnexpectedKeyWordInBeginBlock.DoIdentifier(@Src[CurPos.StartPos]) then
|
||||||
SaveRaiseUnexpectedKeyWordInBeginEndBlock;
|
SaveRaiseUnexpectedKeyWordInBeginEndBlock;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user