浏览代码

fcl-js: started jsonscanner adaption for pas2js

git-svn-id: trunk@40045 -
Mattias Gaertner 6 年之前
父节点
当前提交
75e6356e02
共有 2 个文件被更改,包括 88 次插入78 次删除
  1. 87 77
      packages/fcl-json/src/jsonscanner.pp
  2. 1 1
      utils/pas2js/nodepas2js.pp

+ 87 - 77
packages/fcl-json/src/jsonscanner.pp

@@ -15,6 +15,10 @@
 {$mode objfpc}
 {$h+}
 
+{$ifdef fpc}
+  {$define UsePChar}
+{$endif}
+
 unit jsonscanner;
 
 interface
@@ -48,7 +52,7 @@ type
     tkUnknown
     );
 
-  EScannerError       = class(EParserError);
+  EScannerError = class(EParserError);
 
   TJSONOption = (joUTF8,joStrict,joComments,joIgnoreTrailingComma);
   TJSONOptions = set of TJSONOption;
@@ -62,24 +66,27 @@ Type
 
   TJSONScanner = class
   private
-    FSource : TStringList;
+    FSource: TStringList;
     FCurRow: Integer;
     FCurToken: TJSONToken;
     FCurTokenString: string;
     FCurLine: string;
-    TokenStr: PChar;
+    FTokenStr: {$ifdef UsePChar}PChar{$else}integer{$endif}; // position inside FCurLine
     FOptions : TJSONOptions;
     function GetCurColumn: Integer; inline;
     function GetO(AIndex: TJSONOption): Boolean;
     procedure SetO(AIndex: TJSONOption; AValue: Boolean);
   protected
     procedure Error(const Msg: string);overload;
-    procedure Error(const Msg: string; Const Args: array of Const);overload;
+    procedure Error(const Msg: string;
+      Const Args: array of {$ifdef pas2js}jsvalue{$else}const{$endif});overload;
     function DoFetchToken: TJSONToken; inline;
   public
+    {$ifdef fpc}
     constructor Create(Source : TStream; AUseUTF8 : Boolean = True); overload; deprecated 'use options form instead';
     constructor Create(const Source : String; AUseUTF8 : Boolean = True); overload; deprecated  'use options form instead';
     constructor Create(Source: TStream; AOptions: TJSONOptions); overload;
+    {$endif}
     constructor Create(const Source: String; AOptions: TJSONOptions); overload;
     destructor Destroy; override;
     function FetchToken: TJSONToken;
@@ -122,6 +129,7 @@ const
 
 implementation
 
+{$ifdef fpc}
 constructor TJSONScanner.Create(Source : TStream; AUseUTF8 : Boolean = True);
 
 Var
@@ -155,6 +163,7 @@ begin
   FSource.LoadFromStream(Source);
   FOptions:=AOptions;
 end;
+{$endif}
 
 constructor TJSONScanner.Create(const Source: String; AOptions: TJSONOptions);
 begin
@@ -181,7 +190,8 @@ begin
   raise EScannerError.Create(Msg);
 end;
 
-procedure TJSONScanner.Error(const Msg: string; const Args: array of const);
+procedure TJSONScanner.Error(const Msg: string;
+  const Args: array of {$ifdef pas2js}jsvalue{$else}const{$endif});
 begin
   raise EScannerError.CreateFmt(Msg, Args);
 end;
@@ -194,13 +204,13 @@ function TJSONScanner.DoFetchToken: TJSONToken;
     if Result then
       begin
       FCurLine:=FSource[FCurRow];
-      TokenStr:=PChar(FCurLine);
+      FTokenStr:=PChar(FCurLine);
       Inc(FCurRow);
       end
     else             
       begin
       FCurLine:='';
-      TokenStr:=nil;
+      FTokenStr:=nil;
       end;
   end;
 
@@ -214,7 +224,7 @@ var
   IsStar,EOC: Boolean;
 
 begin
-  if TokenStr = nil then
+  if FTokenStr = nil then
     if not FetchLine then
       begin
       Result := tkEOF;
@@ -224,7 +234,7 @@ begin
 
   FCurTokenString := '';
 
-  case TokenStr[0] of
+  case FTokenStr[0] of
     #0:         // Empty line
       begin
       FetchLine;
@@ -234,33 +244,33 @@ begin
       begin
       Result := tkWhitespace;
       repeat
-        Inc(TokenStr);
-        if TokenStr[0] = #0 then
+        Inc(FTokenStr);
+        if FTokenStr[0] = #0 then
           if not FetchLine then
           begin
             FCurToken := Result;
             exit;
           end;
-      until not (TokenStr[0] in [#9, ' ']);
+      until not (FTokenStr[0] in [#9, ' ']);
       end;
     '"','''':
       begin
-        C:=TokenStr[0];
+        C:=FTokenStr[0];
         If (C='''') and (joStrict in Options) then
-          Error(SErrInvalidCharacter, [CurRow,CurColumn,TokenStr[0]]);
-        Inc(TokenStr);
-        TokenStart := TokenStr;
+          Error(SErrInvalidCharacter, [CurRow,CurColumn,FTokenStr[0]]);
+        Inc(FTokenStr);
+        TokenStart := FTokenStr;
         OldLength := 0;
         FCurTokenString := '';
-        while not (TokenStr[0] in [#0,C]) do
+        while not (FTokenStr[0] in [#0,C]) do
           begin
-          if (TokenStr[0]='\') then
+          if (FTokenStr[0]='\') then
             begin
             // Save length
-            SectionLength := TokenStr - TokenStart;
-            Inc(TokenStr);
+            SectionLength := FTokenStr - TokenStart;
+            Inc(FTokenStr);
             // Read escaped token
-            Case TokenStr[0] of
+            Case FTokenStr[0] of
               '"' : S:='"';
               '''' : S:='''';
               't' : S:=#9;
@@ -275,14 +285,14 @@ begin
                     u:=0;
                     For I:=1 to 4 do
                       begin
-                      Inc(TokenStr);
-                      c2:=TokenStr^;
+                      Inc(FTokenStr);
+                      c2:=FTokenStr^;
                       Case c2 of
                         '0'..'9': u:=u*16+ord(c2)-ord('0');
                         'A'..'F': u:=u*16+ord(c2)-ord('A')+10;
                         'a'..'f': u:=u*16+ord(c2)-ord('a')+10;
                       else
-                        Error(SErrInvalidCharacter, [CurRow,CurColumn,TokenStr[0]]);
+                        Error(SErrInvalidCharacter, [CurRow,CurColumn,FTokenStr[0]]);
                       end;
                       end;
                     // ToDo: 4-bytes UTF16
@@ -293,7 +303,7 @@ begin
                     end;
               #0  : Error(SErrOpenString);
             else
-              Error(SErrInvalidCharacter, [CurRow,CurColumn,TokenStr[0]]);
+              Error(SErrInvalidCharacter, [CurRow,CurColumn,FTokenStr[0]]);
             end;
             SetLength(FCurTokenString, OldLength + SectionLength+1+Length(S));
             if SectionLength > 0 then
@@ -301,61 +311,61 @@ begin
             Move(S[1],FCurTokenString[OldLength + SectionLength+1],Length(S));
             Inc(OldLength, SectionLength+Length(S));
             // Next char
-            TokenStart := TokenStr+1;
+            TokenStart := FTokenStr+1;
             end;
-          if TokenStr[0] = #0 then
+          if FTokenStr[0] = #0 then
             Error(SErrOpenString);
-          Inc(TokenStr);
+          Inc(FTokenStr);
           end;
-        if TokenStr[0] = #0 then
+        if FTokenStr[0] = #0 then
           Error(SErrOpenString);
-        SectionLength := TokenStr - TokenStart;
+        SectionLength := FTokenStr - TokenStart;
         SetLength(FCurTokenString, OldLength + SectionLength);
         if SectionLength > 0 then
           Move(TokenStart^, FCurTokenString[OldLength + 1], SectionLength);
-        Inc(TokenStr);
+        Inc(FTokenStr);
         Result := tkString;
       end;
     ',':
       begin
-        Inc(TokenStr);
+        Inc(FTokenStr);
         Result := tkComma;
       end;
     '0'..'9','.','-':
       begin
-        TokenStart := TokenStr;
+        TokenStart := FTokenStr;
         while true do
         begin
-          Inc(TokenStr);
-          case TokenStr[0] of
+          Inc(FTokenStr);
+          case FTokenStr[0] of
             '.':
               begin
-                if TokenStr[1] in ['0'..'9', 'e', 'E'] then
+                if FTokenStr[1] in ['0'..'9', 'e', 'E'] then
                 begin
-                  Inc(TokenStr);
+                  Inc(FTokenStr);
                   repeat
-                    Inc(TokenStr);
-                  until not (TokenStr[0] in ['0'..'9', 'e', 'E','-','+']);
+                    Inc(FTokenStr);
+                  until not (FTokenStr[0] in ['0'..'9', 'e', 'E','-','+']);
                 end;
                 break;
               end;
             '0'..'9': ;
             'e', 'E':
               begin
-                Inc(TokenStr);
-                if TokenStr[0] in ['-','+']  then
-                  Inc(TokenStr);
-                while TokenStr[0] in ['0'..'9'] do
-                  Inc(TokenStr);
+                Inc(FTokenStr);
+                if FTokenStr[0] in ['-','+']  then
+                  Inc(FTokenStr);
+                while FTokenStr[0] in ['0'..'9'] do
+                  Inc(FTokenStr);
                 break;
               end;
           else
-            if not (TokenStr[0] in [#0,'}',']',',',#9,' ']) then
-               Error(SErrInvalidCharacter, [CurRow,CurColumn,TokenStr[0]]);
+            if not (FTokenStr[0] in [#0,'}',']',',',#9,' ']) then
+               Error(SErrInvalidCharacter, [CurRow,CurColumn,FTokenStr[0]]);
             break;
           end;
         end;
-        SectionLength := TokenStr - TokenStart;
+        SectionLength := FTokenStr - TokenStart;
         FCurTokenString:='';
         SetString(FCurTokenString, TokenStart, SectionLength);
         If (FCurTokenString[1]='.') then
@@ -364,74 +374,74 @@ begin
       end;
     ':':
       begin
-        Inc(TokenStr);
+        Inc(FTokenStr);
         Result := tkColon;
       end;
     '{':
       begin
-        Inc(TokenStr);
+        Inc(FTokenStr);
         Result := tkCurlyBraceOpen;
       end;
     '}':
       begin
-        Inc(TokenStr);
+        Inc(FTokenStr);
         Result := tkCurlyBraceClose;
       end;  
     '[':
       begin
-        Inc(TokenStr);
+        Inc(FTokenStr);
         Result := tkSquaredBraceOpen;
       end;
     ']':
       begin
-        Inc(TokenStr);
+        Inc(FTokenStr);
         Result := tkSquaredBraceClose;
       end;
     '/' :
       begin
       if Not (joComments in Options) then
-        Error(SErrInvalidCharacter, [CurRow,CurCOlumn,TokenStr[0]]);
-      TokenStart:=TokenStr;
-      Inc(TokenStr);
-      Case Tokenstr[0] of
+        Error(SErrInvalidCharacter, [CurRow,CurCOlumn,FTokenStr[0]]);
+      TokenStart:=FTokenStr;
+      Inc(FTokenStr);
+      Case FTokenStr[0] of
         '/' : begin
-              SectionLength := Length(FCurLine)- (TokenStr - PChar(FCurLine));
-              Inc(TokenStr);
+              SectionLength := Length(FCurLine)- (FTokenStr - PChar(FCurLine));
+              Inc(FTokenStr);
               FCurTokenString:='';
-              SetString(FCurTokenString, TokenStr, SectionLength);
+              SetString(FCurTokenString, FTokenStr, SectionLength);
               Fetchline;
               end;
         '*' :
           begin
           IsStar:=False;
-          Inc(TokenStr);
-          TokenStart:=TokenStr;
+          Inc(FTokenStr);
+          TokenStart:=FTokenStr;
           Repeat
-            if (TokenStr[0]=#0) then
+            if (FTokenStr[0]=#0) then
               begin
-              SectionLength := (TokenStr - TokenStart);
+              SectionLength := (FTokenStr - TokenStart);
               S:='';
               SetString(S, TokenStart, SectionLength);
               FCurtokenString:=FCurtokenString+S;
               if not fetchLine then
-                Error(SUnterminatedComment, [CurRow,CurCOlumn,TokenStr[0]]);
-              TokenStart:=TokenStr;
+                Error(SUnterminatedComment, [CurRow,CurCOlumn,FTokenStr[0]]);
+              TokenStart:=FTokenStr;
               end;
-            IsStar:=TokenStr[0]='*';
-            Inc(TokenStr);
-            EOC:=(isStar and (TokenStr[0]='/'));
+            IsStar:=FTokenStr[0]='*';
+            Inc(FTokenStr);
+            EOC:=(isStar and (FTokenStr[0]='/'));
           Until EOC;
           if EOC then
             begin
-            SectionLength := (TokenStr - TokenStart-1);
+            SectionLength := (FTokenStr - TokenStart-1);
             S:='';
             SetString(S, TokenStart, SectionLength);
             FCurtokenString:=FCurtokenString+S;
-            Inc(TokenStr);
+            Inc(FTokenStr);
             end;
           end;
       else
-        Error(SErrInvalidCharacter, [CurRow,CurCOlumn,TokenStr[0]]);
+        Error(SErrInvalidCharacter, [CurRow,CurCOlumn,FTokenStr[0]]);
       end;
       Result:=tkComment;
       end;
@@ -439,11 +449,11 @@ begin
       begin
         tstart:=CurRow;
         Tcol:=CurColumn;
-        TokenStart := TokenStr;
+        TokenStart := FTokenStr;
         repeat
-          Inc(TokenStr);
-        until not (TokenStr[0] in ['A'..'Z', 'a'..'z', '0'..'9', '_']);
-        SectionLength := TokenStr - TokenStart;
+          Inc(FTokenStr);
+        until not (FTokenStr[0] in ['A'..'Z', 'a'..'z', '0'..'9', '_']);
+        SectionLength := FTokenStr - TokenStart;
         FCurTokenString:='';
         SetString(FCurTokenString, TokenStart, SectionLength);
         for it := tkTrue to tkNull do
@@ -459,7 +469,7 @@ begin
           Result:=tkIdentifier;
       end;
   else
-    Error(SErrInvalidCharacter, [CurRow,CurCOlumn,TokenStr[0]]);
+    Error(SErrInvalidCharacter, [CurRow,CurColumn,FTokenStr[0]]);
   end;
 
   FCurToken := Result;
@@ -467,7 +477,7 @@ end;
 
 function TJSONScanner.GetCurColumn: Integer;
 begin
-  Result := TokenStr - PChar(CurLine);
+  Result := FTokenStr - PChar(CurLine);
 end;
 
 function TJSONScanner.GetO(AIndex: TJSONOption): Boolean;

+ 1 - 1
utils/pas2js/nodepas2js.pp

@@ -5,7 +5,7 @@ program nodepas2js;
 uses
   JS, NodeJS, NodeJSFS, Math,
   Classes, SysUtils,
-  jsbase, jstree, jswriter,
+  jsbase, jstree, jswriter, jsonscanner,// JSSrcMap,
   fpjson,
   PasTree, PScanner, PParser, PasResolveEval, PasResolver, PasUseAnalyzer,
   FPPas2Js,