codetools: implemented parsing c enums

git-svn-id: trunk@14291 -
This commit is contained in:
mattias 2008-02-27 22:59:53 +00:00
parent e033e82e6d
commit 0e9a820edc
3 changed files with 93 additions and 9 deletions

View File

@ -50,7 +50,9 @@ const
ccnRoot = 1+ccnBase;
ccnDirective = 2+ccnBase;// e.g. "#define a" ,can be multiple lines, without line end
ccnExtern = 3+ccnBase;// e.g. extern "C" {}
ccnEnum = 4+ccnBase;// e.g. enum {};
ccnEnums = 4+ccnBase;// e.g. enum {};
ccnEnum = 5+ccnBase;// e.g. name = value;
ccnConstant = 6+ccnBase;// e.g. 1
type
TCCodeParserTool = class;
@ -105,6 +107,7 @@ type
procedure MoveCursorToPos(p: integer);
procedure ReadNextAtom;
function ReadTilBracketClose(ExceptionOnNotFound: boolean): boolean;
function AtomIs(const s: shortstring): boolean;
function UpAtomIs(const s: shortstring): boolean;
function AtomIsIdentifier: boolean;
@ -177,7 +180,7 @@ end;
function TCCodeParserTool.EnumToken: boolean;
begin
Result:=true;
CreateChildNode(ccnExtern);
CreateChildNode(ccnEnums);
ReadNextAtom;
if not AtomIs('{') then
RaiseExpectedButAtomFound('{');
@ -187,16 +190,30 @@ begin
ReadNextAtom;
repeat
if AtomIsIdentifier then begin
// read enum
CreateChildNode(ccnEnum);
ReadNextAtom;
if AtomIs('=') then begin
// read value
ReadNextAtom;
ReadConstant;
end;
EndChildNode;
end;
if AtomIs(',') then begin
// next enum
ReadNextAtom;
if not AtomIsIdentifier then
RaiseExpectedButAtomFound('identifier');
end else if AtomIs('}') then begin
break;
end else
RaiseExpectedButAtomFound('{');
RaiseExpectedButAtomFound('}');
until false;
ReadNextAtom;
if not AtomIs(';') then
RaiseExpectedButAtomFound(';');
EndChildNode;
end;
procedure TCCodeParserTool.InitKeyWordList;
@ -244,7 +261,8 @@ end;
procedure TCCodeParserTool.EndChildNode;
begin
DebugLn([GetIndentStr(CurNode.GetLevel*2),'TCCodeParserTool.EndChildNode ']);
CurNode.EndPos:=AtomStart;
if CurNode.EndPos<=0 then
CurNode.EndPos:=AtomStart;
CurNode:=CurNode.Parent;
end;
@ -260,8 +278,23 @@ begin
end;
procedure TCCodeParserTool.ReadConstant;
var
EndPos: LongInt;
begin
if AtomIs(',') or AtomIs(';') then
RaiseExpectedButAtomFound('identifier');
CreateChildNode(ccnConstant);
repeat
if AtomIs('(') or AtomIs('[') then
ReadTilBracketClose(true);
EndPos:=SrcPos;
ReadNextAtom;
if AtomIs(',') or AtomIs(';') or AtomIs(')') or AtomIs(']') or AtomIs('}')
then
break;
until false;
CurNode.EndPos:=EndPos;
EndChildNode;
end;
procedure TCCodeParserTool.RaiseException(const AMessage: string);
@ -336,6 +369,50 @@ begin
DebugLn(['TCCodeParserTool.ReadNextAtom END ',AtomStart,'-',SrcPos,' "',copy(Src,AtomStart,SrcPos-AtomStart),'"']);
end;
function TCCodeParserTool.ReadTilBracketClose(
ExceptionOnNotFound: boolean): boolean;
// AtomStart must be on bracket open
// after reading AtomStart is on closing bracket
var
CloseBracket: Char;
StartPos: LongInt;
begin
case Src[AtomStart] of
'{': CloseBracket:='}';
'[': CloseBracket:=']';
'(': CloseBracket:=')';
'<': CloseBracket:='>';
else
if ExceptionOnNotFound then
RaiseExpectedButAtomFound('(');
exit(false);
end;
StartPos:=AtomStart;
{$IFOPT R+}{$DEFINE RangeChecking}{$ENDIF}
{$R-}
repeat
ReadRawNextCAtom(Src,SrcPos,AtomStart);
if AtomStart>SrcLen then begin
AtomStart:=StartPos;
SrcPos:=AtomStart+1;
if ExceptionOnNotFound then
RaiseException('closing bracket not found');
exit;
end;
case Src[AtomStart] of
'{','(','[':
// skip nested bracketss
begin
if not ReadTilBracketClose(ExceptionOnNotFound) then
exit;
end;
else
if Src[AtomStart]=CloseBracket then exit(true);
end;
until false;
{$IFDEF RangeChecking}{$R+}{$UNDEF RangeChecking}{$ENDIF}
end;
function TCCodeParserTool.AtomIs(const s: shortstring): boolean;
var
len: Integer;

View File

@ -26,10 +26,10 @@
</RunParams>
<RequiredPackages Count="2">
<Item1>
<PackageName Value="LCL"/>
<PackageName Value="CodeTools"/>
</Item1>
<Item2>
<PackageName Value="CodeTools"/>
<PackageName Value="LCL"/>
</Item2>
</RequiredPackages>
<Units Count="1">

View File

@ -106,16 +106,19 @@ function ReadTilCBracketClose(const Source: string; var Position: integer
): boolean;
// Position must start on a bracket
// at end Position will be right behind closing bracket
// if no closing bracket found then Position will be on the starting position
var
Len: Integer;
CloseBracket: Char;
AtomStart: LongInt;
StartPos: LongInt;
begin
{$IFOPT R+}{$DEFINE RangeChecking}{$ENDIF}
{$R-}
Result:=false;
Len:=length(Source);
if Position>Len then exit;
StartPos:=Position;
case Source[Position] of
'{': CloseBracket:='}';
'[': CloseBracket:=']';
@ -128,13 +131,17 @@ begin
AtomStart:=Position;
repeat
ReadRawNextCAtom(Source,Position,AtomStart);
if AtomStart>Len then exit;
if AtomStart>Len then begin
Position:=StartPos;
exit;
end;
case Source[AtomStart] of
'{','(','[':
// skip nested bracketss
begin
Position:=AtomStart;
if not ReadTilCBracketClose(Source,Position) then exit;
if not ReadTilCBracketClose(Source,Position) then
exit;
end;
else
if Source[AtomStart]=CloseBracket then exit(true);