mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2026-01-06 02:40:40 +01:00
codetools: c parser: supporting defined name
git-svn-id: trunk@15950 -
This commit is contained in:
parent
e449094a7f
commit
2ada1f890f
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user