DBG improved expression parsing, array[1]+array[2]

git-svn-id: trunk@36200 -
This commit is contained in:
martin 2012-03-21 23:11:01 +00:00
parent d79ff1435a
commit cfae3de029
3 changed files with 43 additions and 17 deletions

View File

@ -1085,7 +1085,7 @@ begin
if AIdx < 0 then exit; if AIdx < 0 then exit;
for i := 0 to AIdx do begin for i := 0 to AIdx do begin
IdxPart := IndexPart[i]; IdxPart := TGDBExpressionPartArrayIdx(Parts[i + 1]);
PTResult := IdxPart.ArrayPTypeResult; PTResult := IdxPart.ArrayPTypeResult;
if PCastCnt > 0 then dec(PCastCnt); if PCastCnt > 0 then dec(PCastCnt);
@ -1361,7 +1361,7 @@ const
// include "." (dots). currently there is no need to break expressions like "foo.bar" // include "." (dots). currently there is no need to break expressions like "foo.bar"
// Include "^" (deref) // Include "^" (deref)
// do NOT include "@", it is applied after []() resolution // do NOT include "@", it is applied after []() resolution
WordChar = [' ', #9, 'a'..'z', 'A'..'Z', '0'..'9', '_', '.', '^']; WordChar = ['a'..'z', 'A'..'Z', '0'..'9', '_', '#', '$', '%', '&', '^', '.'];
var var
CurPtr, EndPtr: PChar; CurPtr, EndPtr: PChar;
CurPartPtr: PChar; CurPartPtr: PChar;
@ -1372,11 +1372,26 @@ var
end; end;
procedure ScanToWordEnd; procedure ScanToWordEnd;
var
c: Char;
f: Boolean;
begin begin
// include "." (dots). currently there is no need to break expressions like "foo.bar" // include "." (dots). currently there is no need to break expressions like "foo.bar"
// Include "^" (deref) // Include "^" (deref)
while (CurPtr < EndPtr) and (CurPtr^ in WordChar) while (CurPtr < EndPtr) do begin
do inc(CurPtr); c := CurPtr^;
if (c in WordChar) then begin
inc(CurPtr);
end
else if (c in [' ', #9]) then begin
f := ((CurPtr-1)^ in ['.', '^']);
SkipSpaces;
if not(f or ((CurPtr < EndPtr) and (CurPtr^ in ['.', '^'])) ) then
break;
end
else
break;
end;
end; end;
procedure ScanToWordStart; procedure ScanToWordStart;
@ -1480,7 +1495,6 @@ begin
if CurPtr = EndPtr then exit; // no fixup needed if CurPtr = EndPtr then exit; // no fixup needed
CurPtr := AText; CurPtr := AText;
CurArray := nil;
CurList:= TGDBExpressionPartList.Create; CurList:= TGDBExpressionPartList.Create;
while CurPtr < EndPtr do begin while CurPtr < EndPtr do begin
@ -1497,16 +1511,15 @@ begin
else else
if CurPtr^ in WordChar if CurPtr^ in WordChar
then begin then begin
if CurArray <> nil then CurArray.NeedTypeCast := True;
CurArray := nil;
CurPartPtr := CurPtr; CurPartPtr := CurPtr;
ScanToWordEnd; ScanToWordEnd;
CurList.Add(TGDBExpression.CreateSimple(CurPartPtr, CurPtr - CurPartPtr)); CurList.Add(TGDBExpression.CreateSimple(CurPartPtr, CurPtr - CurPartPtr));
if CurPtr^ in WordChar then // 2 words => named operator (and/or)
AddExpPart(CurList);
end end
else else
if (CurList.PartCount > 0) and (CurPtr^ = '[') if (CurList.PartCount > 0) and (CurPtr^ = '[')
then begin then begin
if CurArray <> nil then CurArray.NeedTypeCast := True;
CurArray := TGDBExpressionPartArray.Create(MoveListToCopy(CurList)); CurArray := TGDBExpressionPartArray.Create(MoveListToCopy(CurList));
CurList.Add(CurArray); CurList.Add(CurArray);
while (CurPtr^ = '[') do begin while (CurPtr^ = '[') do begin
@ -1515,12 +1528,12 @@ begin
CurArray.AddIndex(TGDBExpressionPartArrayIdx.Create(CurPartPtr, CurPtr - CurPartPtr)); CurArray.AddIndex(TGDBExpressionPartArrayIdx.Create(CurPartPtr, CurPtr - CurPartPtr));
SkipSpaces; SkipSpaces;
end; end;
if (CurPtr < EndPtr ) and (CurPtr^ in ['.', '^', '(']) then
CurArray.NeedTypeCast := True;
end end
else else
if (CurList.PartCount > 0) and (CurPtr^ = '(') if (CurList.PartCount > 0) and (CurPtr^ = '(')
then begin then begin
if CurArray <> nil then CurArray.NeedTypeCast := True;
CurArray := nil;
CurCast := TGDBExpressionPartCastCall.Create(MoveListToCopy(CurList)); CurCast := TGDBExpressionPartCastCall.Create(MoveListToCopy(CurList));
CurList.Add(CurCast); CurList.Add(CurCast);
CurPartPtr := CurPtr; CurPartPtr := CurPtr;
@ -1528,7 +1541,6 @@ begin
CurCast.AddBrackets(TGDBExpressionPartBracketed.Create(CurPartPtr, CurPtr - CurPartPtr)); CurCast.AddBrackets(TGDBExpressionPartBracketed.Create(CurPartPtr, CurPtr - CurPartPtr));
end end
else begin else begin
CurArray := nil;
CurPartPtr := CurPtr; CurPartPtr := CurPtr;
ScanToWordStart; ScanToWordStart;
CurList.Add(TGDBExpression.CreateSimple(CurPartPtr, CurPtr - CurPartPtr)); CurList.Add(TGDBExpression.CreateSimple(CurPartPtr, CurPtr - CurPartPtr));

View File

@ -611,13 +611,13 @@ procedure TTestGdbType.TestExpressionBreaker;
FreeAndNil(b); FreeAndNil(b);
r := nil; r := nil;
b := TGDBExpression.Create(e); b := TGDBExpression.Create(e);
v := b.NeedValidation(r);
debugln('##### '+e); debugln('##### '+e);
DumpGExp(b); DumpGExp(b);
AssertEquals(e+' as text', e, b.Text);
v := b.NeedValidation(r);
if r <> nil then DumpReq(r); if r <> nil then DumpReq(r);
debugln; debugln;
AssertEquals(e+' as text', e, b.Text);
end; end;
procedure ContinueExpr(b: TGDBExpression; out r: PGDBPTypeRequest; out v: Boolean); procedure ContinueExpr(b: TGDBExpression; out r: PGDBPTypeRequest; out v: Boolean);
begin begin
@ -797,6 +797,17 @@ begin
n := 'Cast(foo^.bar[1][foo[2]]+Call[x()]((f+1)^))+bar(1).z.x[1](m)(n)'; n := 'Cast(foo^.bar[1][foo[2]]+Call[x()]((f+1)^))+bar(1).z.x[1](m)(n)';
InitExpr(n, b, r, v); InitExpr(n, b, r, v);
n := 'abc[1,2,3].x[1]';
InitExpr(n, b, r, v);
n := 'abc[1,2,3].x and abc[1,2][3].y';
InitExpr(n, b, r, v);
n := '1+abc[1,2,3].x and b . cc [ 1 , 2 or x ]';
InitExpr(n, b, r, v);
b.Free; b.Free;
end; end;

View File

@ -1309,10 +1309,13 @@ begin
//TDynStatArrayPRec2 = array of array [3..5] of ^TRecForArray2; //TDynStatArrayPRec2 = array of array [3..5] of ^TRecForArray2;
(* Array in expression*) (* Array in expression*)
//Add(v+'ArgTDynArrayTRec1[0].a+'+v+'ArgTDynArrayTRec1[1].a', wdfDefault, '^181$', skSimple, M_Int, [fTpMtch] ); Add(v+'ArgTDynArrayTRec1[0].a+'+v+'ArgTDynArrayTRec1[1].a', wdfDefault, '^181$', skSimple, M_Int+'|long', [fTpMtch] );
//Add(v+'ArgTDynArrayTRec1[0].a+'+'ArgTDynArrayTRec1[1].a', wdfDefault, '^181$', skSimple, M_Int, [fTpMtch] ); Add(v+'ArgTDynArrayTRec1[0].a+'+'ArgTDynArrayTRec1[1].a', wdfDefault, '^181$', skSimple, M_Int+'|long', [fTpMtch] );
//Add('ArgTDynArrayTRec1[0].a+'+v+'ArgTDynArrayTRec1[1].a', wdfDefault, '^181$', skSimple, M_Int, [fTpMtch] ); Add('ArgTDynArrayTRec1[0].a+'+v+'ArgTDynArrayTRec1[1].a', wdfDefault, '^181$', skSimple, M_Int+'|long', [fTpMtch] );
//Add(v+'ArgTDynArrayTRec1[0].a+'+v+'ArgTDynArrayTRec1[1].a', wdfDefault, '^181$', skSimple, M_Int, [fTpMtch] ); Add(v+'ArgTDynArrayTRec1[0].a and '+v+'ArgTDynArrayTRec1[1].a', wdfDefault, '^90$', skSimple, M_Int+'|long', [fTpMtch] );
Add(v+'ArgTDynDynArrayTRec1[1][1].a+'+v+'ArgTDynArrayPRec1[1]^.a', wdfDefault, '^177$', skSimple, M_Int+'|long', [fTpMtch] );
Add(v+'ArgTDynArrayPRec1[1]^.a+'+v+'ArgTDynDynArrayTRec1[1][1].a', wdfDefault, '^177$', skSimple, M_Int+'|long', [fTpMtch] );
{%endregion DYN ARRAY (norm)} {%endregion DYN ARRAY (norm)}