On 22 August 2010 18:25, Michael Van Canneyt wrote:
>
> Why ? To the compiler there is no difference between EOL and whitespace.
>
> If you want to generate it with the exact layout, then, yes.
> But for profiling I don't see the need.

Maybe to the compiler it doesn't matter, but to a human trying to
debug their profiler to see if they inserted code in the correct
place, or to see why code doesn't compile any more after the profiler
modified the code - such "human readable code" is rather important.
:)
If no NewLine characters are inserted into the newly generated units,
a compiler error on line 1 doesn't help the developer much. Line 1
could be 50k bytes or more long.

Lazarus can't open the file (error message says it doesn't look like a
text file), other editor show one line, but clips text because they
can't display such a long single line of text. The profiler becomes a
near perfect obfuscater. :-)


>
> Well, I still fail to see why you need the tab and EOL.

Well, does it hurt having them tokenized?

If anybody other than me comes up with a new idea/way of using the
fcl-passrc parser on tokenizer - maybe they would like to rebuild
source code at some point. Without tokens telling you where EOL used
to be or TAB characters used to be (though the latter is not to
important), it does limit it's functionality.

Attached is a file processed with the profiler and fcl-passrc that
doesn't use tkLineEnding or tkTab. It's rather hard to read and fix
compiler errors introduced by the profile inserting code.

I don't see why introducing such new tokens is bad? It can only make
the tokenizer and parser more useful in the long term.



-- 
Regards,
  - Graeme -


_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/
  unit fpputils;     interface  uses  fpprof,  pscanner, PasTree, SysUtils, Classes, FPPWriter;  const  FPPROF_EXT = '.fpprof';  type  TPasToken = record  token: TToken;  value: string;  end;  PPasToken = ^TPasToken;      TPasTokenList = class(TObject)  FFileName: string;  private  FList: TFPList;  function GetList(index: integer): TPasToken;  procedure SetFileName(const AValue: string);  procedure SetList(AIndex: integer; const AValue: TPasToken);   public  constructor Create;  destructor Destroy; override;  function Count: integer;  function ParseSource(AFileName: string): boolean;  procedure Add(AToken: TToken; AValue: string);  procedure Clear;  procedure Insert(APos: integer; AToken: TToken; AValue: string);  procedure SaveToFile(const AFileName: string);  property FileName: string read FFileName write SetFileName;  property List[index: integer]: TPasToken read GetList write SetList; default;  end;   TModTokenProc = procedure(AFileName: string; tokenlist: TPasTokenList);  procedure FileSearch(SearchDir: string; ExtensionMask: string; var FileList: TStrings; Recursive: boolean = false); procedure InsertProfilingCode(FileList: TStrings; ModTokenProc: TModTokenProc); procedure RemoveProfilingCodeFromFile(const FileName: string); procedure RemoveProfilingCode(FileList: TStrings);  implementation  procedure FileSearch(SearchDir: string; ExtensionMask: string;  var FileList: TStrings; Recursive: boolean = false); var  Info : TSearchRec;  ExtensionList: TStrings; begin  fpprof_entry_profile; 
 SearchDir := IncludeTrailingPathDelimiter(SearchDir);   ExtensionList := TStringList.Create;  ExtensionList.Delimiter := ';';  ExtensionList.DelimitedText := ExtensionMask;   if FindFirst(SearchDir+AllFilesMask, faAnyFile and faDirectory, Info) = 0 then  begin  repeat  if Recursive then  if ((Info.Attr and faDirectory) = faDirectory) and (Info.Name <> '.') and (Info.Name <> '..')then  FileSearch(SearchDir + Info.Name, ExtensionMask, FileList, Recursive);   if ExtensionList.IndexOf(ExtractFileExt(Info.Name)) <> -1 then  begin  if FileList.IndexOf(SearchDir + Info.Name) = -1 then  FileList.Add(SearchDir + Info.Name);  end;  until FindNext(Info)<>0;  end;  FindClose(Info);   ExtensionList.Free;  fpprof_exit_profile; 
end;  procedure InsertProfilingCode(FileList: TStrings; ModTokenProc: TModTokenProc); var  i: integer;  PasTokenList: TPasTokenList;  Success: boolean;  writer: TFPPWriter; begin  fpprof_entry_profile; 
 FileList.SaveToFile('./file_processed_list.txt');  PasTokenList := TPasTokenList.Create;  writer := TFPPWriter.Create;  writer.CreateIgnored;     for i := 0 to FileList.Count - 1 do  begin  write('insert: ', FileList[i]);   try  Success := PasTokenList.ParseSource(FileList[i]);   Success := Success and RenameFile(FileList[i], FileList[i] + FPPROF_EXT);     if Assigned(ModTokenProc) then  ModTokenProc(FileList[i], PasTokenList);   PasTokenList.SaveToFile(FileList[i]);    if Success then  writeln(' .......... OK')  except  writeln(' .......... FAIL');  writer.AddIgnoredFile(FileList[i]);  end;   PasTokenList.Clear;  end;   writer.Save;  writer.Free;   PasTokenList.Free;  FileList.Free;  fpprof_exit_profile; 
end;  procedure RemoveProfilingCodeFromFile(const FileName: string); var  NewFileName: string; begin  fpprof_entry_profile; 
 NewFileName := Copy(FileName, 1, Length(FileName) - Length(FPPROF_EXT));   write('revert: ', NewFileName);   DeleteFile(NewFileName);  if RenameFile(FileName, NewFileName) then  writeln(' .......... OK')  else  writeln(' .......... FAIL');  fpprof_exit_profile; 
end;  procedure RemoveProfilingCode(FileList: TStrings); var  i: integer; begin  fpprof_entry_profile; 
   for i := 0 to FileList.Count - 1 do  RemoveProfilingCodeFromFile(FileList[i]);  fpprof_exit_profile; 
end;    function TPasTokenList.GetList(index: integer): TPasToken; begin  fpprof_entry_profile; 
 Result := TPasToken(FList[index]^);  fpprof_exit_profile; 
end;  procedure TPasTokenList.SetFileName(const AValue: string); begin  fpprof_entry_profile; 
 if FFileName=AValue then exit;  FFileName:=AValue;   fpprof_exit_profile; 
end;  procedure TPasTokenList.SetList(AIndex: integer; const AValue: TPasToken); begin  fpprof_entry_profile; 
 FList.Add(@AValue);  fpprof_exit_profile; 
end;  constructor TPasTokenList.Create; begin  fpprof_entry_profile; 
 FList := TFPList.Create;  fpprof_exit_profile; 
end;  destructor TPasTokenList.Destroy; begin  fpprof_entry_profile; 
 Clear;  FList.Free;  inherited Destroy;  fpprof_exit_profile; 
end;  procedure TPasTokenList.Clear; var  i: integer; begin  fpprof_entry_profile; 
 for i := 0 to FList.Count - 1 do  Dispose(PPasToken(FList[i]));   FList.Clear;  fpprof_exit_profile; 
end;  procedure TPasTokenList.Insert(APos: integer; AToken: TToken; AValue: string); var  pt: ^TPasToken; begin  fpprof_entry_profile; 
 New(pt);  pt^.token := AToken;  pt^.Value := AValue;  FList.Insert(APos, pt);  fpprof_exit_profile; 
end;  procedure TPasTokenList.SaveToFile(const AFileName: string); var  t: text;  i: integer; begin  fpprof_entry_profile; 
 assign(t, AFileName);  rewrite(t);   for i := FList.Count-1 downto 0 do  begin  case TPasToken(FList[i]^).token of  tkWhitespace: write(t, ' ');  tkString: write(t,  TPasToken(FList[i]^).value );  tkBraceOpen: write(t, '(');  tkBraceClose: write(t, ')');  tkMul: write(t, '*');  tkPlus: write(t, '+');  tkComma: write(t, ',');  tkMinus: write(t, '-');  tkDot: write(t, '.');  tkDivision: write(t, '/');  tkColon: write(t, ':');  tkSemicolon: write(t, ';');  tkLessThan: write(t, '<');  tkEqual: write(t, '=');  tkGreaterThan: write(t, '>');  tkAt: write(t, '@');  tkSquaredBraceOpen: write(t, '[');  tkSquaredBraceClose: write(t, ']');  tkCaret: write(t, '^');  tkDotDot: write(t, '..');  tkAssign: write(t, ':=');  tkNotEqual: write(t, '<>');  tkLessEqualThan: write(t, '<=');  tkGreaterEqualThan: write(t, '>=');  tkPower: write(t, '**');  tkSymmetricalDifference: write(t, '><');  tkLineEnding: writeln(t, LineEnding);  tkTab: writeln(t, #9);   else    if TPasToken(FList[i]^).token <> tkComment then  write(t, TPasToken(FList[i]^).value);  end;  end;   close(t);  fpprof_exit_profile; 
end;  function TPasTokenList.ParseSource(AFileName: string): boolean; var  pas: TPascalScanner;  fr: TFileResolver;  index: integer;  token: TToken; begin  fpprof_entry_profile; 
 Result := False;   fr := TFileResolver.Create;  pas := TPascalScanner.Create(fr);   try  pas.OpenFile(AFileName);   index := 0;  repeat  inc(index);   token := pas.FetchToken;   Add(token, pas.CurTokenString);     until pas.CurToken = tkEOF;   Result := True;  finally  pas.Free;  fr.Free;  end;  fpprof_exit_profile; 
end;  procedure TPasTokenList.Add(AToken: TToken; AValue: string); begin  fpprof_entry_profile; 
 Insert(0, AToken, AValue);  fpprof_exit_profile; 
end;  function TPasTokenList.Count: integer; begin  fpprof_entry_profile; 
 Result := FList.Count;  fpprof_exit_profile; 
end;  end. 
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply via email to