Sfoglia il codice sorgente

* Accept quoted identifiers, using double quotes

git-svn-id: trunk@34423 -
michael 9 anni fa
parent
commit
1001bac6bb

+ 15 - 2
packages/fcl-base/src/fpexprpars.pp

@@ -781,6 +781,7 @@ Resourcestring
   SErrCommaExpected =  'Expected comma (,) at position %d, but got %s';
   SErrInvalidNumberChar = 'Unexpected character in number : %s';
   SErrInvalidNumber = 'Invalid numerical value : %s';
+  SErrUnterminatedIdentifier = 'Unterminated quoted identifier: %s';
   SErrNoOperand = 'No operand for unary operation %s';
   SErrNoleftOperand = 'No left operand for binary operation %s';
   SErrNoRightOperand = 'No right operand for binary operation %s';
@@ -1195,7 +1196,19 @@ begin
   C:=CurrentChar;
   while (not IsWordDelim(C)) and (C<>cNull) do
     begin
-    FToken:=FToken+C;
+    if (C<>'"') then
+      FToken:=FToken+C
+    else
+      begin
+      C:=NextPos;
+      While Not (C in [cNull,'"']) do
+        begin
+        FToken:=FToken+C;
+        C:=NextPos;
+        end;
+      if (C<>'"') then
+        ScanError(Format(SErrUnterminatedIdentifier,[FToken]));
+      end;
     C:=NextPos;
     end;
   S:=LowerCase(Token);
@@ -1236,7 +1249,7 @@ begin
     Result:=DoString
   else if IsDigit(C) then
     Result:=DoNumber
-  else if IsAlpha(C) then
+  else if IsAlpha(C) or (C='"') then
     Result:=DoIdentifier
   else
     ScanError(Format(SErrUnknownCharacter,[FPos,C]))  ;

+ 24 - 1
packages/fcl-base/tests/testexprpars.pp

@@ -31,6 +31,7 @@ type
     FP : TFPExpressionScanner;
     FInvalidString : String;
     procedure DoInvalidNumber(AString: String);
+    procedure TestIdentifier(const ASource, ATokenName: string);
     procedure TestInvalidNumber;
   protected
     procedure SetUp; override; 
@@ -46,6 +47,7 @@ type
     Procedure TestInvalidCharacter;
     Procedure TestUnterminatedString;
     Procedure TestQuotesInString;
+    Procedure TestIdentifiers;
   end;
 
   { TMyFPExpressionParser }
@@ -1320,7 +1322,7 @@ procedure TTestExpressionScanner.DoInvalidNumber(AString : String);
 
 begin
   FInvalidString:=AString;
-  AssertException('Invalid number "'+AString+'"',EExprScanner,@TestInvalidNumber);
+  AssertException('Invalid number "'+AString+'" ',EExprScanner,@TestInvalidNumber);
 end;
 
 procedure TTestExpressionScanner.TestNumber;
@@ -1356,6 +1358,27 @@ begin
   TestString('''s it''''''',ttString);
 end;
 
+procedure TTestExpressionScanner.TestIdentifier(Const ASource,ATokenName : string);
+
+begin
+  FP.Source:=ASource;
+  AssertEquals('Token type',ttIdentifier,FP.GetToken);
+  AssertEquals('Token name',ATokenName,FP.Token);
+end;
+
+procedure TTestExpressionScanner.TestIdentifiers;
+begin
+  TestIdentifier('a','a');
+  TestIdentifier(' a','a');
+  TestIdentifier('a ','a');
+  TestIdentifier('a^b','a');
+  TestIdentifier('a-b','a');
+  TestIdentifier('a.b','a.b');
+  TestIdentifier('"a b"','a b');
+  TestIdentifier('c."a b"','c.a b');
+  TestIdentifier('c."ab"','c.ab');
+end;
+
 procedure TTestExpressionScanner.SetUp; 
 begin
   FP:=TFPExpressionScanner.Create;