codetools: c parser: supporting defined name

git-svn-id: trunk@15950 -
This commit is contained in:
mattias 2008-08-04 15:42:14 +00:00
parent e449094a7f
commit 2ada1f890f
3 changed files with 103 additions and 16 deletions

View File

@ -382,6 +382,7 @@ function TCCodeParserTool.DirectiveToken: boolean;
procedure ReadExpression;
var
BracketLevel: Integer;
NeedBracket: Boolean;
begin
BracketLevel:=0;
repeat
@ -407,16 +408,22 @@ function TCCodeParserTool.DirectiveToken: boolean;
// valid operator
end else if IsIdentChar[Src[AtomStart]] then begin
if AtomIs('defined') then begin
// read defined(macro)
ReadRawNextCAtom(Src,SrcPos,AtomStart);
if not AtomIsChar('(') then
RaiseExpectedButAtomFound('(');
// read defined(macro)
// or read defined macro
ReadRawNextCAtom(Src,SrcPos,AtomStart);
if AtomIsChar('(') then begin
NeedBracket:=true;
ReadRawNextCAtom(Src,SrcPos,AtomStart);
end else begin
NeedBracket:=false;
end;
if not AtomIsIdentifier then
RaiseExpectedButAtomFound('macro');
ReadRawNextCAtom(Src,SrcPos,AtomStart);
if not AtomIsChar(')') then
RaiseExpectedButAtomFound(')');
if NeedBracket then begin
ReadRawNextCAtom(Src,SrcPos,AtomStart);
if not AtomIsChar(')') then
RaiseExpectedButAtomFound(')');
end;
end else begin
// constant
end;

View File

@ -19,6 +19,7 @@
invalid).
The function Eval evaluates expressions and understands the operators
AND, OR, XOR, NOT, (, ), =, <, >, <=, >=, <>
defined()
}
unit ExprEval;
@ -85,6 +86,23 @@ type
procedure WriteDebugReport;
end;
{ TExpressionSolver
Checks if expression is always true 1, always false 0, or something }
TExpressionSolver = class
public
//Defines: TStringToStringTree;
//Undefines: TStringToStringTree;
ErrorMsg: string; // last error message
ErrorPos: integer;// last error position
constructor Create;
destructor Destroy; override;
function Solve(const Expr: string; out ExprResult: string): boolean;
function Solve(const Src: string; StartPos, EndPos: integer;
out ExprResult: string): boolean;
end;
implementation
var
@ -734,6 +752,65 @@ begin
dbgs(ConsistencyCheck));
end;
{ TExpressionSolver }
constructor TExpressionSolver.Create;
begin
end;
destructor TExpressionSolver.Destroy;
begin
inherited Destroy;
end;
function TExpressionSolver.Solve(const Expr: string; out
ExprResult: string): boolean;
begin
Result:=Solve(Expr,1,length(Expr),ExprResult);
end;
function TExpressionSolver.Solve(const Src: string;
StartPos, EndPos: integer; out ExprResult: string): boolean;
{ '' -> ''
true = nonzero, false = zero
defined(name)
sizeof(type)
unary operators: not, !
binary operators: = <> >= <= > < and or xor shl shr
round brackets ()
}
var
AtomStart: LongInt;
SrcPos: LongInt;
function AtomIs(const s: shortstring): boolean;
var
len: Integer;
i: Integer;
begin
len:=length(s);
if (len<>SrcPos-AtomStart) then exit(false);
if SrcPos>EndPos then exit(false);
for i:=1 to len do
if Src[AtomStart+i-1]<>s[i] then exit(false);
Result:=true;
end;
begin
if StartPos>=EndPos then begin
ExprResult:='';
exit(true);
end;
SrcPos:=StartPos;
AtomStart:=SrcPos;
//ReadNextCAtom(Source,SrcPos,AtomStart);
if AtomIs('!') then begin
end;
end;
initialization
InternalInit;

View File

@ -1012,6 +1012,7 @@ var
AtomStart: integer;
BracketLvl: Integer;
LastToken: TTokenType;
NeedBracket: Boolean;
function AtomIs(const s: shortstring): boolean;
var
@ -1105,12 +1106,12 @@ begin
end;
if AtomIs('defined') then begin
Add(ttValue);
// read defined(name)
// read defined(name) or defined name
ReadRawNextCAtom(CCode,p,AtomStart);
if not AtomIs('(') then begin
ErrorExpectedButFound('(');
exit;
end;
if AtomIs('(') then
NeedBracket:=true
else
NeedBracket:=false;
Add(ttBracketOpen);
ReadRawNextCAtom(CCode,p,AtomStart);
if (AtomStart>=EndPos) or (not IsIdentStartChar[CCode[AtomStart]])
@ -1123,10 +1124,12 @@ begin
Add(ttValue,'FPC')
else
Add(ttValue);
ReadRawNextCAtom(CCode,p,AtomStart);
if not AtomIs(')') then begin
ErrorExpectedButFound(')');
exit;
if NeedBracket then begin
ReadRawNextCAtom(CCode,p,AtomStart);
if not AtomIs(')') then begin
ErrorExpectedButFound(')');
exit;
end;
end;
Add(ttBracketClose);
end else begin