pas2jspparser.pp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. { Author: Mattias Gaertner 2017 [email protected]
  2. Abstract:
  3. Extends the FCL Pascal parser for the language subset of pas2js.
  4. }
  5. unit Pas2jsPParser;
  6. {$mode objfpc}{$H+}
  7. {$inline on}
  8. interface
  9. uses
  10. Classes, SysUtils, PParser, PScanner, PasTree, PasResolver, fppas2js,
  11. Pas2jsLogger;
  12. const // Messages
  13. nFinalizationNotSupported = 3001;
  14. sFinalizationNotSupported = 'Finalization section is not supported.';
  15. type
  16. { TPas2jsPasParser }
  17. TPas2jsPasParser = class(TPasParser)
  18. private
  19. FLog: TPas2jsLogger;
  20. public
  21. constructor Create(AScanner: TPascalScanner;
  22. AFileResolver: TBaseFileResolver; AEngine: TPasTreeContainer);
  23. procedure SetLastMsg(MsgType: TMessageType; MsgNumber: integer;
  24. Const Fmt : String; Args : Array of const);
  25. procedure RaiseParserError(MsgNumber: integer; Args: array of const);
  26. procedure ParseSubModule(var Module: TPasModule);
  27. property Log: TPas2jsLogger read FLog write FLog;
  28. end;
  29. TOnFindModule = function(const aUnitname: String): TPasModule of object;
  30. TOnCheckSrcName = procedure(const aElement: TPasElement) of object;
  31. { TPas2jsCompilerResolver }
  32. TPas2jsCompilerResolver = class(TPas2JSResolver)
  33. private
  34. FLog: TPas2jsLogger;
  35. FOnCheckSrcName: TOnCheckSrcName;
  36. FOnContinueParsing: TNotifyEvent;
  37. FOnFindModule: TOnFindModule;
  38. FP2JParser: TPas2jsPasParser;
  39. public
  40. function CreateElement(AClass: TPTreeElement; const AName: String;
  41. AParent: TPasElement; AVisibility: TPasMemberVisibility;
  42. const ASrcPos: TPasSourcePos): TPasElement;
  43. overload; override;
  44. function FindModule(const aUnitname: String): TPasModule; override;
  45. procedure ContinueParsing; override;
  46. public
  47. Owner: TObject;
  48. property OnContinueParsing: TNotifyEvent read FOnContinueParsing write FOnContinueParsing;
  49. property OnFindModule: TOnFindModule read FOnFindModule write FOnFindModule;
  50. property OnCheckSrcName: TOnCheckSrcName read FOnCheckSrcName write FOnCheckSrcName;
  51. property Log: TPas2jsLogger read FLog write FLog;
  52. property P2JParser: TPas2jsPasParser read FP2JParser write FP2JParser;
  53. end;
  54. procedure RegisterMessages(Log: TPas2jsLogger);
  55. implementation
  56. procedure RegisterMessages(Log: TPas2jsLogger);
  57. var
  58. LastMsgNumber: integer;
  59. procedure r(MsgType: TMessageType; MsgNumber: integer; const MsgPattern: string);
  60. var
  61. s: String;
  62. begin
  63. if (LastMsgNumber>=0) and (MsgNumber<>LastMsgNumber+1) then
  64. begin
  65. s:='gap in registered message numbers: '+IntToStr(LastMsgNumber)+' '+IntToStr(MsgNumber);
  66. writeln('Pas2jsPParser.RegisterMessages ',s);
  67. raise Exception.Create(s);
  68. end;
  69. Log.RegisterMsg(MsgType,MsgNumber,MsgPattern);
  70. LastMsgNumber:=MsgNumber;
  71. end;
  72. begin
  73. LastMsgNumber:=-1;
  74. r(mtError,nFinalizationNotSupported,sFinalizationNotSupported);
  75. end;
  76. { TPas2jsPasParser }
  77. constructor TPas2jsPasParser.Create(AScanner: TPascalScanner;
  78. AFileResolver: TBaseFileResolver; AEngine: TPasTreeContainer);
  79. begin
  80. inherited Create(AScanner,AFileResolver,AEngine);
  81. Options:=Options+[po_asmwhole,po_resolvestandardtypes];
  82. end;
  83. procedure TPas2jsPasParser.SetLastMsg(MsgType: TMessageType;
  84. MsgNumber: integer; const Fmt: String; Args: array of const);
  85. begin
  86. inherited SetLastMsg(MsgType,MsgNumber,Fmt,Args);
  87. end;
  88. procedure TPas2jsPasParser.RaiseParserError(MsgNumber: integer; Args: array of const);
  89. var
  90. Msg: TPas2jsMessage;
  91. begin
  92. Msg:=Log.FindMsg(MsgNumber,true);
  93. SetLastMsg(Msg.Typ,MsgNumber,Msg.Pattern,Args);
  94. raise EParserError.Create(LastMsg,Scanner.CurFilename,
  95. Scanner.CurRow,Scanner.CurColumn);
  96. end;
  97. procedure TPas2jsPasParser.ParseSubModule(var Module: TPasModule);
  98. begin
  99. Module:=nil;
  100. NextToken;
  101. SaveComments;
  102. case CurToken of
  103. tkUnit:
  104. ParseUnit(Module);
  105. tkLibrary:
  106. ParseLibrary(Module);
  107. else
  108. ExpectToken(tkUnit);
  109. end;
  110. end;
  111. { TPas2jsCompilerResolver }
  112. function TPas2jsCompilerResolver.CreateElement(AClass: TPTreeElement;
  113. const AName: String; AParent: TPasElement; AVisibility: TPasMemberVisibility;
  114. const ASrcPos: TPasSourcePos): TPasElement;
  115. begin
  116. if AClass=TFinalizationSection then
  117. (CurrentParser as TPas2jsPasParser).RaiseParserError(nFinalizationNotSupported,[]);
  118. Result:=inherited;
  119. if (Result is TPasModule) then
  120. OnCheckSrcName(Result);
  121. end;
  122. function TPas2jsCompilerResolver.FindModule(const aUnitname: String): TPasModule;
  123. begin
  124. Result:=OnFindModule(aUnitname);
  125. end;
  126. procedure TPas2jsCompilerResolver.ContinueParsing;
  127. begin
  128. OnContinueParsing(Self);
  129. end;
  130. end.