taskjuggler 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (415) hide show
  1. data/CHANGELOG +119 -0
  2. data/benchmarks/allocatedSlots.tjp +1602 -0
  3. data/benchmarks/booking.tjp +40 -30
  4. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/css/tjmanual.css +0 -0
  5. data/{test/TestSuite/Scheduler/Correct → benchmarks}/css/tjreport.css +1 -0
  6. data/benchmarks/gantt.tjp +57 -0
  7. data/benchmarks/htmltaskreport.tjp +26 -1
  8. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/details.png +0 -0
  9. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/flag-green.png +0 -0
  10. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/flag-red.png +0 -0
  11. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/flag-yellow.png +0 -0
  12. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/resource.png +0 -0
  13. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/resourcegroup.png +0 -0
  14. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/task.png +0 -0
  15. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/taskgroup.png +0 -0
  16. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/trend-down.png +0 -0
  17. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/trend-flat.png +0 -0
  18. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/trend-up.png +0 -0
  19. data/benchmarks/profile.clt +36082 -0
  20. data/benchmarks/profile.html +58182 -0
  21. data/benchmarks/runbench.rb +6 -0
  22. data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/scripts/wz_tooltip.js +0 -0
  23. data/doc/AppConfig.html +85 -37
  24. data/doc/Arguments.html +11 -1
  25. data/doc/CHANGELOG.html +131 -2
  26. data/doc/COPYING.html +11 -1
  27. data/doc/Object.html +12 -3
  28. data/doc/README.html +11 -1
  29. data/doc/RuntimeConfig.html +11 -1
  30. data/doc/String.html +11 -1
  31. data/doc/StringIO.html +11 -1
  32. data/doc/TaskJuggler.html +250 -219
  33. data/doc/TaskJuggler/Account.html +11 -1
  34. data/doc/TaskJuggler/AccountAttribute.html +11 -1
  35. data/doc/TaskJuggler/AccountScenario.html +11 -1
  36. data/doc/TaskJuggler/Allocation.html +11 -1
  37. data/doc/TaskJuggler/AllocationAttribute.html +11 -1
  38. data/doc/TaskJuggler/AttributeBase.html +11 -1
  39. data/doc/TaskJuggler/AttributeDefinition.html +11 -1
  40. data/doc/TaskJuggler/BatchProcessor.html +11 -1
  41. data/doc/TaskJuggler/Booking.html +11 -1
  42. data/doc/TaskJuggler/BookingListAttribute.html +11 -1
  43. data/doc/TaskJuggler/BooleanAttribute.html +11 -1
  44. data/doc/TaskJuggler/CSVFile.html +12 -2
  45. data/doc/TaskJuggler/CellSettingPattern.html +11 -1
  46. data/doc/TaskJuggler/CellSettingPatternList.html +11 -1
  47. data/doc/TaskJuggler/Charge.html +11 -1
  48. data/doc/TaskJuggler/ChargeListAttribute.html +11 -1
  49. data/doc/TaskJuggler/ChargeSet.html +11 -1
  50. data/doc/TaskJuggler/ChargeSetListAttribute.html +11 -1
  51. data/doc/TaskJuggler/CollisionDetector.html +1063 -0
  52. data/doc/TaskJuggler/ColumnListAttribute.html +11 -1
  53. data/doc/TaskJuggler/ColumnTable.html +11 -1
  54. data/doc/TaskJuggler/Daemon.html +11 -1
  55. data/doc/TaskJuggler/{OnShiftCache.html → DataCache.html} +127 -139
  56. data/doc/TaskJuggler/DataCacheEntry.html +711 -0
  57. data/doc/TaskJuggler/DateAttribute.html +11 -1
  58. data/doc/TaskJuggler/DefinitionListAttribute.html +11 -1
  59. data/doc/TaskJuggler/DependencyListAttribute.html +11 -1
  60. data/doc/TaskJuggler/DurationAttribute.html +16 -5
  61. data/doc/TaskJuggler/FileList.html +11 -1
  62. data/doc/TaskJuggler/FileRecord.html +11 -1
  63. data/doc/TaskJuggler/FixnumAttribute.html +19 -9
  64. data/doc/TaskJuggler/FlagListAttribute.html +29 -19
  65. data/doc/TaskJuggler/FloatAttribute.html +23 -13
  66. data/doc/TaskJuggler/FormatListAttribute.html +19 -9
  67. data/doc/TaskJuggler/GanttChart.html +94 -133
  68. data/doc/TaskJuggler/GanttContainer.html +11 -1
  69. data/doc/TaskJuggler/GanttHeader.html +11 -1
  70. data/doc/TaskJuggler/GanttHeaderScaleItem.html +11 -1
  71. data/doc/TaskJuggler/GanttLine.html +11 -1
  72. data/doc/TaskJuggler/GanttLoadStack.html +11 -1
  73. data/doc/TaskJuggler/GanttMilestone.html +11 -1
  74. data/doc/TaskJuggler/GanttRouter.html +247 -596
  75. data/doc/TaskJuggler/GanttTaskBar.html +11 -1
  76. data/doc/TaskJuggler/HTMLDocument.html +11 -1
  77. data/doc/TaskJuggler/HTMLGraphics.html +11 -1
  78. data/doc/TaskJuggler/Interval.html +11 -1
  79. data/doc/TaskJuggler/IntervalListAttribute.html +33 -23
  80. data/doc/TaskJuggler/JobInfo.html +11 -1
  81. data/doc/TaskJuggler/Journal.html +11 -1
  82. data/doc/TaskJuggler/JournalEntry.html +11 -1
  83. data/doc/TaskJuggler/JournalEntryList.html +11 -1
  84. data/doc/TaskJuggler/KeywordArray.html +11 -1
  85. data/doc/TaskJuggler/KeywordDocumentation.html +16 -6
  86. data/doc/TaskJuggler/Limits.html +11 -1
  87. data/doc/TaskJuggler/Limits/Limit.html +11 -1
  88. data/doc/TaskJuggler/LimitsAttribute.html +24 -14
  89. data/doc/TaskJuggler/ListAttributeBase.html +11 -1
  90. data/doc/TaskJuggler/Log.html +11 -1
  91. data/doc/TaskJuggler/LogFile.html +11 -1
  92. data/doc/TaskJuggler/LogicalAttribute.html +11 -1
  93. data/doc/TaskJuggler/LogicalExpression.html +11 -1
  94. data/doc/TaskJuggler/LogicalExpressionAttribute.html +19 -9
  95. data/doc/TaskJuggler/LogicalFlag.html +11 -1
  96. data/doc/TaskJuggler/LogicalFunction.html +11 -1
  97. data/doc/TaskJuggler/LogicalOperation.html +11 -1
  98. data/doc/TaskJuggler/Macro.html +11 -1
  99. data/doc/TaskJuggler/MacroTable.html +11 -1
  100. data/doc/TaskJuggler/ManagerResponsibilities.html +11 -1
  101. data/doc/TaskJuggler/ManagerStatusRecord.html +11 -1
  102. data/doc/TaskJuggler/Message.html +11 -1
  103. data/doc/TaskJuggler/MessageHandler.html +11 -1
  104. data/doc/TaskJuggler/Navigator.html +12 -2
  105. data/doc/TaskJuggler/NavigatorElement.html +11 -1
  106. data/doc/TaskJuggler/NikuProject.html +11 -1
  107. data/doc/TaskJuggler/NikuReport.html +11 -1
  108. data/doc/TaskJuggler/NikuResource.html +11 -1
  109. data/doc/TaskJuggler/NodeListAttribute.html +17 -7
  110. data/doc/TaskJuggler/PlaceHolderCell.html +722 -0
  111. data/doc/TaskJuggler/ProcessIntercom.html +11 -1
  112. data/doc/TaskJuggler/ProcessIntercomIface.html +11 -1
  113. data/doc/TaskJuggler/Project.html +587 -500
  114. data/doc/TaskJuggler/ProjectBroker.html +11 -1
  115. data/doc/TaskJuggler/ProjectBrokerIface.html +11 -1
  116. data/doc/TaskJuggler/ProjectFileParser.html +205 -192
  117. data/doc/TaskJuggler/ProjectFileScanner.html +230 -207
  118. data/doc/TaskJuggler/ProjectRecord.html +11 -1
  119. data/doc/TaskJuggler/ProjectServer.html +11 -1
  120. data/doc/TaskJuggler/ProjectServerIface.html +11 -1
  121. data/doc/TaskJuggler/PropertyAttribute.html +19 -9
  122. data/doc/TaskJuggler/PropertyList.html +95 -83
  123. data/doc/TaskJuggler/PropertySet.html +11 -1
  124. data/doc/TaskJuggler/PropertyTreeNode.html +11 -1
  125. data/doc/TaskJuggler/Query.html +234 -232
  126. data/doc/TaskJuggler/RTFHandlers.html +11 -1
  127. data/doc/TaskJuggler/RTFNavigator.html +11 -1
  128. data/doc/TaskJuggler/RTFQuery.html +11 -1
  129. data/doc/TaskJuggler/RTFReport.html +11 -1
  130. data/doc/TaskJuggler/RTFReportLink.html +11 -1
  131. data/doc/TaskJuggler/RTFWithQuerySupport.html +11 -1
  132. data/doc/TaskJuggler/RealFormat.html +12 -2
  133. data/doc/TaskJuggler/RealFormatAttribute.html +15 -5
  134. data/doc/TaskJuggler/ReferenceAttribute.html +38 -28
  135. data/doc/TaskJuggler/Report.html +96 -113
  136. data/doc/TaskJuggler/ReportBase.html +161 -152
  137. data/doc/TaskJuggler/ReportContext.html +11 -1
  138. data/doc/TaskJuggler/ReportServer.html +59 -48
  139. data/doc/TaskJuggler/ReportServerIface.html +51 -41
  140. data/doc/TaskJuggler/ReportServerRecord.html +11 -1
  141. data/doc/TaskJuggler/ReportServlet.html +11 -1
  142. data/doc/TaskJuggler/ReportTable.html +46 -25
  143. data/doc/TaskJuggler/ReportTableCell.html +296 -275
  144. data/doc/TaskJuggler/ReportTableColumn.html +14 -4
  145. data/doc/TaskJuggler/ReportTableLegend.html +11 -1
  146. data/doc/TaskJuggler/ReportTableLine.html +19 -7
  147. data/doc/TaskJuggler/Resource.html +12 -2
  148. data/doc/TaskJuggler/ResourceListAttribute.html +40 -30
  149. data/doc/TaskJuggler/ResourceListRE.html +11 -1
  150. data/doc/TaskJuggler/ResourceScenario.html +708 -565
  151. data/doc/TaskJuggler/RichText.html +54 -36
  152. data/doc/TaskJuggler/RichTextAttribute.html +31 -21
  153. data/doc/TaskJuggler/RichTextDocument.html +11 -1
  154. data/doc/TaskJuggler/RichTextElement.html +11 -1
  155. data/doc/TaskJuggler/RichTextFunctionExample.html +11 -1
  156. data/doc/TaskJuggler/RichTextFunctionHandler.html +11 -1
  157. data/doc/TaskJuggler/RichTextImage.html +11 -1
  158. data/doc/TaskJuggler/RichTextIntermediate.html +81 -71
  159. data/doc/TaskJuggler/RichTextParser.html +88 -33
  160. data/doc/TaskJuggler/RichTextScanner.html +45 -35
  161. data/doc/TaskJuggler/RichTextSnip.html +11 -1
  162. data/doc/TaskJuggler/RichTextSyntaxRules.html +436 -389
  163. data/doc/TaskJuggler/Scenario.html +11 -1
  164. data/doc/TaskJuggler/ScenarioData.html +11 -1
  165. data/doc/TaskJuggler/ScenarioListAttribute.html +23 -13
  166. data/doc/TaskJuggler/Scoreboard.html +92 -73
  167. data/doc/TaskJuggler/SheetHandlerBase.html +11 -1
  168. data/doc/TaskJuggler/SheetReceiver.html +11 -1
  169. data/doc/TaskJuggler/SheetSender.html +11 -1
  170. data/doc/TaskJuggler/Shift.html +11 -1
  171. data/doc/TaskJuggler/ShiftAssignment.html +11 -1
  172. data/doc/TaskJuggler/ShiftAssignments.html +11 -1
  173. data/doc/TaskJuggler/ShiftAssignmentsAttribute.html +24 -14
  174. data/doc/TaskJuggler/ShiftScenario.html +11 -1
  175. data/doc/TaskJuggler/SimpleQueryExpander.html +11 -1
  176. data/doc/TaskJuggler/SortListAttribute.html +21 -11
  177. data/doc/TaskJuggler/SourceFileInfo.html +11 -1
  178. data/doc/TaskJuggler/StatusSheetReceiver.html +11 -1
  179. data/doc/TaskJuggler/StatusSheetReport.html +11 -1
  180. data/doc/TaskJuggler/StatusSheetSender.html +112 -11
  181. data/doc/TaskJuggler/StringAttribute.html +23 -13
  182. data/doc/TaskJuggler/SymbolAttribute.html +19 -9
  183. data/doc/TaskJuggler/SyntaxReference.html +80 -71
  184. data/doc/TaskJuggler/TOCEntry.html +11 -1
  185. data/doc/TaskJuggler/TSResourceRecord.html +11 -1
  186. data/doc/TaskJuggler/TSTaskRecord.html +11 -1
  187. data/doc/TaskJuggler/TableColumnDefinition.html +11 -1
  188. data/doc/TaskJuggler/TableOfContents.html +11 -1
  189. data/doc/TaskJuggler/TableReport.html +422 -411
  190. data/doc/TaskJuggler/Task.html +11 -1
  191. data/doc/TaskJuggler/TaskDependency.html +11 -1
  192. data/doc/TaskJuggler/TaskListAttribute.html +33 -23
  193. data/doc/TaskJuggler/TaskListRE.html +11 -1
  194. data/doc/TaskJuggler/TaskScenario.html +2007 -1919
  195. data/doc/TaskJuggler/TextFormatter.html +11 -1
  196. data/doc/TaskJuggler/TextParser.html +421 -612
  197. data/doc/TaskJuggler/TextParser/Pattern.html +410 -211
  198. data/doc/TaskJuggler/TextParser/Rule.html +224 -152
  199. data/doc/TaskJuggler/TextParser/StackElement.html +190 -28
  200. data/doc/TaskJuggler/TextParser/State.html +989 -0
  201. data/doc/TaskJuggler/TextParser/StateTransition.html +782 -0
  202. data/doc/TaskJuggler/TextParser/TextParserResultArray.html +25 -14
  203. data/doc/TaskJuggler/TextParser/TokenDoc.html +11 -1
  204. data/doc/TaskJuggler/TextReport.html +11 -1
  205. data/doc/TaskJuggler/TextScanner.html +285 -273
  206. data/doc/TaskJuggler/TextScanner/BufferStreamHandle.html +17 -7
  207. data/doc/TaskJuggler/TextScanner/FileStreamHandle.html +24 -14
  208. data/doc/TaskJuggler/TextScanner/MacroStackEntry.html +11 -1
  209. data/doc/TaskJuggler/TextScanner/StreamHandle.html +64 -52
  210. data/doc/TaskJuggler/TimeSheet.html +11 -1
  211. data/doc/TaskJuggler/TimeSheetReceiver.html +11 -1
  212. data/doc/TaskJuggler/TimeSheetRecord.html +11 -1
  213. data/doc/TaskJuggler/TimeSheetReport.html +11 -1
  214. data/doc/TaskJuggler/TimeSheetSender.html +11 -1
  215. data/doc/TaskJuggler/TimeSheetSummary.html +11 -1
  216. data/doc/TaskJuggler/TimeSheets.html +11 -1
  217. data/doc/TaskJuggler/Tj3AppBase.html +11 -1
  218. data/doc/TaskJuggler/Tj3Client.html +11 -1
  219. data/doc/TaskJuggler/Tj3Daemon.html +11 -1
  220. data/doc/TaskJuggler/Tj3SheetAppBase.html +11 -1
  221. data/doc/TaskJuggler/Tj3SsReceiver.html +11 -1
  222. data/doc/TaskJuggler/Tj3SsSender.html +11 -1
  223. data/doc/TaskJuggler/Tj3TsReceiver.html +11 -1
  224. data/doc/TaskJuggler/Tj3TsSender.html +11 -1
  225. data/doc/TaskJuggler/Tj3TsSummary.html +11 -1
  226. data/doc/TaskJuggler/TjException.html +11 -1
  227. data/doc/TaskJuggler/TjTime.html +474 -324
  228. data/doc/TaskJuggler/TjpExample.html +11 -1
  229. data/doc/TaskJuggler/TjpExportRE.html +11 -1
  230. data/doc/TaskJuggler/TjpSyntaxRules.html +3731 -3662
  231. data/doc/TaskJuggler/URLParameter.html +11 -1
  232. data/doc/TaskJuggler/UserManual.html +11 -1
  233. data/doc/TaskJuggler/VimSyntax.html +11 -1
  234. data/doc/TaskJuggler/WebServer.html +11 -1
  235. data/doc/TaskJuggler/WorkingHours.html +295 -221
  236. data/doc/TaskJuggler/WorkingHoursAttribute.html +11 -1
  237. data/doc/TaskJuggler/XMLBlob.html +11 -1
  238. data/doc/TaskJuggler/XMLComment.html +11 -1
  239. data/doc/TaskJuggler/XMLDocument.html +11 -1
  240. data/doc/TaskJuggler/XMLElement.html +11 -1
  241. data/doc/TaskJuggler/XMLNamedText.html +11 -1
  242. data/doc/TaskJuggler/XMLText.html +11 -1
  243. data/doc/index.html +694 -624
  244. data/doc/lib/AppConfig_rb.html +1 -1
  245. data/doc/lib/Attributes_rb.html +1 -1
  246. data/doc/lib/Booking_rb.html +1 -1
  247. data/doc/lib/DataCache_rb.html +69 -0
  248. data/doc/lib/KeywordDocumentation_rb.html +1 -1
  249. data/doc/lib/ProjectFileParser_rb.html +1 -1
  250. data/doc/lib/ProjectFileScanner_rb.html +1 -1
  251. data/doc/lib/Project_rb.html +1 -1
  252. data/doc/lib/PropertyList_rb.html +1 -1
  253. data/doc/lib/Query_rb.html +1 -1
  254. data/doc/lib/RealFormat_rb.html +1 -1
  255. data/doc/lib/ResourceScenario_rb.html +1 -1
  256. data/doc/lib/Resource_rb.html +1 -1
  257. data/doc/lib/RichTextParser_rb.html +1 -1
  258. data/doc/lib/RichTextScanner_rb.html +1 -1
  259. data/doc/lib/RichTextSyntaxRules_rb.html +1 -1
  260. data/doc/lib/RichText_rb.html +1 -1
  261. data/doc/lib/Scoreboard_rb.html +1 -1
  262. data/doc/lib/StatusSheetSender_rb.html +1 -1
  263. data/doc/lib/SyntaxReference_rb.html +1 -1
  264. data/doc/lib/TaskJuggler_rb.html +1 -1
  265. data/doc/lib/TaskScenario_rb.html +3 -1
  266. data/doc/lib/TextParser/Pattern_rb.html +3 -1
  267. data/doc/lib/TextParser/Rule_rb.html +3 -1
  268. data/doc/lib/TextParser/StackElement_rb.html +3 -1
  269. data/doc/lib/TextParser/State_rb.html +65 -0
  270. data/doc/lib/TextParser_rb.html +1 -1
  271. data/doc/lib/TextScanner_rb.html +1 -1
  272. data/doc/lib/Tj3Config_rb.html +1 -1
  273. data/doc/lib/TjTime_rb.html +1 -1
  274. data/doc/lib/TjpSyntaxRules_rb.html +1 -1
  275. data/doc/lib/WorkingHours_rb.html +3 -1
  276. data/doc/lib/daemon/ReportServer_rb.html +1 -1
  277. data/doc/lib/reports/CSVFile_rb.html +1 -1
  278. data/doc/lib/reports/CollisionDetector_rb.html +67 -0
  279. data/doc/lib/reports/GanttChart_rb.html +1 -1
  280. data/doc/lib/reports/GanttRouter_rb.html +3 -1
  281. data/doc/lib/reports/Navigator_rb.html +1 -1
  282. data/doc/lib/reports/ReportBase_rb.html +1 -1
  283. data/doc/lib/reports/ReportTableCell_rb.html +1 -1
  284. data/doc/lib/reports/ReportTableColumn_rb.html +1 -1
  285. data/doc/lib/reports/ReportTableLine_rb.html +1 -1
  286. data/doc/lib/reports/ReportTable_rb.html +1 -1
  287. data/doc/lib/reports/Report_rb.html +1 -1
  288. data/doc/lib/reports/TableReport_rb.html +1 -1
  289. data/doc/lib/taskjuggler3_rb.html +1 -1
  290. data/examples/tutorial.tjp +1 -2
  291. data/lib/AppConfig.rb +10 -4
  292. data/lib/Attributes.rb +4 -4
  293. data/lib/DataCache.rb +124 -0
  294. data/lib/KeywordDocumentation.rb +5 -5
  295. data/lib/Project.rb +54 -10
  296. data/lib/ProjectFileParser.rb +10 -9
  297. data/lib/ProjectFileScanner.rb +38 -25
  298. data/lib/PropertyList.rb +6 -4
  299. data/lib/Query.rb +0 -8
  300. data/lib/RealFormat.rb +1 -1
  301. data/lib/Resource.rb +1 -1
  302. data/lib/ResourceScenario.rb +96 -31
  303. data/lib/RichText.rb +17 -5
  304. data/lib/RichTextParser.rb +22 -9
  305. data/lib/RichTextScanner.rb +34 -34
  306. data/lib/RichTextSyntaxRules.rb +41 -36
  307. data/lib/Scoreboard.rb +16 -7
  308. data/lib/StatusSheetSender.rb +63 -0
  309. data/lib/SyntaxReference.rb +9 -10
  310. data/lib/TaskJuggler.rb +28 -4
  311. data/lib/TaskScenario.rb +66 -19
  312. data/lib/TextParser.rb +219 -384
  313. data/lib/TextParser/Pattern.rb +168 -49
  314. data/lib/TextParser/Rule.rb +33 -17
  315. data/lib/TextParser/StackElement.rb +42 -2
  316. data/lib/TextParser/State.rb +175 -0
  317. data/lib/TextScanner.rb +19 -15
  318. data/lib/Tj3Config.rb +1 -1
  319. data/lib/TjTime.rb +111 -3
  320. data/lib/TjpSyntaxRules.rb +122 -66
  321. data/lib/WorkingHours.rb +91 -186
  322. data/lib/daemon/ReportServer.rb +3 -2
  323. data/lib/reports/CSVFile.rb +1 -1
  324. data/lib/reports/CollisionDetector.rb +177 -0
  325. data/lib/reports/GanttChart.rb +25 -41
  326. data/lib/reports/GanttRouter.rb +104 -233
  327. data/lib/reports/Navigator.rb +1 -1
  328. data/lib/reports/Report.rb +9 -33
  329. data/lib/reports/ReportBase.rb +0 -1
  330. data/lib/reports/ReportTable.rb +19 -8
  331. data/lib/reports/ReportTableCell.rb +61 -25
  332. data/lib/reports/ReportTableColumn.rb +2 -2
  333. data/lib/reports/ReportTableLine.rb +4 -2
  334. data/lib/reports/TableReport.rb +1 -0
  335. data/lib/taskjuggler3.rb +0 -1
  336. data/manual/Installation +7 -3
  337. data/manual/Intro +12 -10
  338. data/manual/The_TaskJuggler_Syntax +4 -4
  339. data/test/TestSuite/CSV-Reports/celltext-Reference.csv +14 -14
  340. data/test/TestSuite/CSV-Reports/genrefs +1 -1
  341. data/test/TestSuite/CSV-Reports/resourcereport-Reference.csv +4 -4
  342. data/test/TestSuite/CSV-Reports/resourcereport_with_tasks-Reference.csv +22 -22
  343. data/test/TestSuite/CSV-Reports/sortByTree-Reference.csv +14 -14
  344. data/test/TestSuite/CSV-Reports/sortBy_duration.down-Reference.csv +14 -14
  345. data/test/TestSuite/CSV-Reports/sortBy_effort.up-Reference.csv +14 -14
  346. data/test/TestSuite/CSV-Reports/sortBy_plan.start.down-Reference.csv +14 -14
  347. data/test/TestSuite/CSV-Reports/taskreport-Reference.csv +14 -14
  348. data/test/TestSuite/CSV-Reports/taskreport_with_resources-Reference.csv +32 -24
  349. data/test/TestSuite/CSV-Reports/weekly-Reference.csv +13 -0
  350. data/test/TestSuite/CSV-Reports/weekly.tjp +9 -0
  351. data/test/TestSuite/HTML-Reports/css/tjreport.css +7 -2
  352. data/test/TestSuite/HTML-Reports/depArrows.html +839 -830
  353. data/test/TestSuite/HTML-Reports/depArrows.tjp +12 -12
  354. data/test/TestSuite/HTML-Reports/profile.html +37581 -0
  355. data/test/TestSuite/ReportGenerator/Errors/no_report_defined.tjp +7 -0
  356. data/test/TestSuite/ReportGenerator/Errors/rtp_report_recursion.tjp +1 -1
  357. data/test/TestSuite/StatusSheets/TimeSheets/2002-03-01/missing-reports +2 -0
  358. data/test/TestSuite/StatusSheets/run +2 -0
  359. data/test/TestSuite/Syntax/Correct/Booking.tjp +13 -5
  360. data/test/TestSuite/Syntax/Correct/ResourceRoot.tjp +21 -0
  361. data/test/TestSuite/Syntax/Correct/RollupResource.tjp +21 -0
  362. data/test/TestSuite/Syntax/Correct/TaskRoot.tjp +1 -1
  363. data/test/TestSuite/Syntax/Errors/empty.tjp +1 -1
  364. data/test/TestSuite/Syntax/Errors/include_before_project.tjp +2 -0
  365. data/test/TestSuite/Syntax/Errors/no_reduce.tjp +6 -0
  366. data/test/TestSuite/Syntax/Errors/unsupported_token.tjp +1 -1
  367. data/test/TestSuite/TimeSheets/run +1 -1
  368. data/test/test_CSV-Reports.rb +2 -4
  369. data/test/test_CollisionDetector.rb +85 -0
  370. data/test/test_Project.rb +2 -2
  371. data/test/test_ProjectFileScanner.rb +73 -31
  372. data/test/test_Query.rb +2 -2
  373. data/test/test_ReportGenerator.rb +1 -1
  374. data/test/test_RichText.rb +4 -4
  375. data/test/test_WorkingHours.rb +150 -11
  376. metadata +75 -67
  377. data/test/TestSuite/ReportGenerator/Errors/css/tjreport.css +0 -407
  378. data/test/TestSuite/ReportGenerator/Errors/rtp_report_recursion.html +0 -26
  379. data/test/TestSuite/Scheduler/Correct/Allocate.html +0 -3210
  380. data/test/TestSuite/Scheduler/Correct/Container.html +0 -349
  381. data/test/TestSuite/Scheduler/Correct/Limits.html +0 -4964
  382. data/test/TestSuite/Scheduler/Correct/Shift.html +0 -1719
  383. data/test/TestSuite/Scheduler/Correct/Shift2.html +0 -476
  384. data/test/TestSuite/Scheduler/Correct/css/tjmanual.css +0 -66
  385. data/test/TestSuite/Scheduler/Correct/icons/details.png +0 -0
  386. data/test/TestSuite/Scheduler/Correct/icons/flag-green.png +0 -0
  387. data/test/TestSuite/Scheduler/Correct/icons/flag-red.png +0 -0
  388. data/test/TestSuite/Scheduler/Correct/icons/flag-yellow.png +0 -0
  389. data/test/TestSuite/Scheduler/Correct/icons/resource.png +0 -0
  390. data/test/TestSuite/Scheduler/Correct/icons/resourcegroup.png +0 -0
  391. data/test/TestSuite/Scheduler/Correct/icons/task.png +0 -0
  392. data/test/TestSuite/Scheduler/Correct/icons/taskgroup.png +0 -0
  393. data/test/TestSuite/Scheduler/Correct/icons/trend-down.png +0 -0
  394. data/test/TestSuite/Scheduler/Correct/icons/trend-flat.png +0 -0
  395. data/test/TestSuite/Scheduler/Correct/icons/trend-up.png +0 -0
  396. data/test/TestSuite/Scheduler/Correct/scripts/wz_tooltip.js +0 -1301
  397. data/test/TestSuite/Scheduler/Errors/css/tjmanual.css +0 -66
  398. data/test/TestSuite/Scheduler/Errors/css/tjreport.css +0 -407
  399. data/test/TestSuite/Scheduler/Errors/icons/details.png +0 -0
  400. data/test/TestSuite/Scheduler/Errors/icons/flag-green.png +0 -0
  401. data/test/TestSuite/Scheduler/Errors/icons/flag-red.png +0 -0
  402. data/test/TestSuite/Scheduler/Errors/icons/flag-yellow.png +0 -0
  403. data/test/TestSuite/Scheduler/Errors/icons/resource.png +0 -0
  404. data/test/TestSuite/Scheduler/Errors/icons/resourcegroup.png +0 -0
  405. data/test/TestSuite/Scheduler/Errors/icons/task.png +0 -0
  406. data/test/TestSuite/Scheduler/Errors/icons/taskgroup.png +0 -0
  407. data/test/TestSuite/Scheduler/Errors/icons/trend-down.png +0 -0
  408. data/test/TestSuite/Scheduler/Errors/icons/trend-flat.png +0 -0
  409. data/test/TestSuite/Scheduler/Errors/icons/trend-up.png +0 -0
  410. data/test/TestSuite/Scheduler/Errors/scripts/wz_tooltip.js +0 -1301
  411. data/test/TestSuite/StatusSheets/resrep.tji +0 -7
  412. data/test/TestSuite/StatusSheets/tj3d.log +0 -312
  413. data/test/TestSuite/Syntax/Correct/Managers.html +0 -263
  414. data/test/TestSuite/TimeSheets/acceptable_intervals +0 -1
  415. data/test/TestSuite/TimeSheets/statussheets.log +0 -1
@@ -155,12 +155,18 @@
155
155
 
156
156
  <li><a href="../TaskJuggler/ChargeSetListAttribute.html">TaskJuggler::ChargeSetListAttribute</a></li>
157
157
 
158
+ <li><a href="../TaskJuggler/CollisionDetector.html">TaskJuggler::CollisionDetector</a></li>
159
+
158
160
  <li><a href="../TaskJuggler/ColumnListAttribute.html">TaskJuggler::ColumnListAttribute</a></li>
159
161
 
160
162
  <li><a href="../TaskJuggler/ColumnTable.html">TaskJuggler::ColumnTable</a></li>
161
163
 
162
164
  <li><a href="../TaskJuggler/Daemon.html">TaskJuggler::Daemon</a></li>
163
165
 
166
+ <li><a href="../TaskJuggler/DataCache.html">TaskJuggler::DataCache</a></li>
167
+
168
+ <li><a href="../TaskJuggler/DataCacheEntry.html">TaskJuggler::DataCacheEntry</a></li>
169
+
164
170
  <li><a href="../TaskJuggler/DateAttribute.html">TaskJuggler::DateAttribute</a></li>
165
171
 
166
172
  <li><a href="../TaskJuggler/DefinitionListAttribute.html">TaskJuggler::DefinitionListAttribute</a></li>
@@ -267,7 +273,7 @@
267
273
 
268
274
  <li><a href="../TaskJuggler/NodeListAttribute.html">TaskJuggler::NodeListAttribute</a></li>
269
275
 
270
- <li><a href="../TaskJuggler/OnShiftCache.html">TaskJuggler::OnShiftCache</a></li>
276
+ <li><a href="../TaskJuggler/PlaceHolderCell.html">TaskJuggler::PlaceHolderCell</a></li>
271
277
 
272
278
  <li><a href="../TaskJuggler/ProcessIntercom.html">TaskJuggler::ProcessIntercom</a></li>
273
279
 
@@ -447,6 +453,10 @@
447
453
 
448
454
  <li><a href="../TaskJuggler/TextParser/StackElement.html">TaskJuggler::TextParser::StackElement</a></li>
449
455
 
456
+ <li><a href="../TaskJuggler/TextParser/State.html">TaskJuggler::TextParser::State</a></li>
457
+
458
+ <li><a href="../TaskJuggler/TextParser/StateTransition.html">TaskJuggler::TextParser::StateTransition</a></li>
459
+
450
460
  <li><a href="../TaskJuggler/TextParser/TextParserResultArray.html">TaskJuggler::TextParser::TextParserResultArray</a></li>
451
461
 
452
462
  <li><a href="../TaskJuggler/TextParser/TokenDoc.html">TaskJuggler::TextParser::TokenDoc</a></li>
@@ -44,6 +44,9 @@
44
44
  <li><a href="../lib/TextParser/Pattern_rb.html?TB_iframe=true&amp;height=550&amp;width=785"
45
45
  class="thickbox" title="lib/TextParser/Pattern.rb">lib/TextParser/Pattern.rb</a></li>
46
46
 
47
+ <li><a href="../lib/TextParser/State_rb.html?TB_iframe=true&amp;height=550&amp;width=785"
48
+ class="thickbox" title="lib/TextParser/State.rb">lib/TextParser/State.rb</a></li>
49
+
47
50
  <li><a href="../lib/TextParser/Rule_rb.html?TB_iframe=true&amp;height=550&amp;width=785"
48
51
  class="thickbox" title="lib/TextParser/Rule.rb">lib/TextParser/Rule.rb</a></li>
49
52
 
@@ -84,6 +87,10 @@
84
87
 
85
88
  <li><span class="type">CLASS</span> <a href="TextParser/StackElement.html">TaskJuggler::TextParser::StackElement</a></li>
86
89
 
90
+ <li><span class="type">CLASS</span> <a href="TextParser/State.html">TaskJuggler::TextParser::State</a></li>
91
+
92
+ <li><span class="type">CLASS</span> <a href="TextParser/StateTransition.html">TaskJuggler::TextParser::StateTransition</a></li>
93
+
87
94
  <li><span class="type">CLASS</span> <a href="TextParser/TextParserResultArray.html">TaskJuggler::TextParser::TextParserResultArray</a></li>
88
95
 
89
96
  <li><span class="type">CLASS</span> <a href="TextParser/TokenDoc.html">TaskJuggler::TextParser::TokenDoc</a></li>
@@ -102,36 +109,34 @@
102
109
 
103
110
  <li><a href="#method-i-checkRule">#checkRule</a></li>
104
111
 
112
+ <li><a href="#method-i-dumpStack">#dumpStack</a></li>
113
+
105
114
  <li><a href="#method-i-error">#error</a></li>
106
115
 
107
- <li><a href="#method-i-findPattern">#findPattern</a></li>
116
+ <li><a href="#method-i-finishPattern">#finishPattern</a></li>
108
117
 
109
118
  <li><a href="#method-i-getNextToken">#getNextToken</a></li>
110
119
 
111
- <li><a href="#method-i-getTransitions">#getTransitions</a></li>
112
-
113
120
  <li><a href="#method-i-initRules">#initRules</a></li>
114
121
 
115
122
  <li><a href="#method-i-limitTokenSet">#limitTokenSet</a></li>
116
123
 
117
- <li><a href="#method-i-matchingRules">#matchingRules</a></li>
118
-
119
124
  <li><a href="#method-i-newRule">#newRule</a></li>
120
125
 
121
126
  <li><a href="#method-i-optional">#optional</a></li>
122
127
 
123
128
  <li><a href="#method-i-parse">#parse</a></li>
124
129
 
125
- <li><a href="#method-i-parseRuleNR">#parseRuleNR</a></li>
126
-
127
- <li><a href="#method-i-parseRuleR">#parseRuleR</a></li>
130
+ <li><a href="#method-i-parseFSM">#parseFSM</a></li>
128
131
 
129
132
  <li><a href="#method-i-pattern">#pattern</a></li>
130
133
 
131
- <li><a href="#method-i-processNormalElements">#processNormalElements</a></li>
132
-
133
134
  <li><a href="#method-i-repeatable">#repeatable</a></li>
134
135
 
136
+ <li><a href="#method-i-restoreFsmStack">#restoreFsmStack</a></li>
137
+
138
+ <li><a href="#method-i-saveFsmStack">#saveFsmStack</a></li>
139
+
135
140
  <li><a href="#method-i-sourceFileInfo">#sourceFileInfo</a></li>
136
141
 
137
142
  <li><a href="#method-i-updateParserTables">#updateParserTables</a></li>
@@ -216,12 +221,18 @@
216
221
 
217
222
  <li><a href="../TaskJuggler/ChargeSetListAttribute.html">TaskJuggler::ChargeSetListAttribute</a></li>
218
223
 
224
+ <li><a href="../TaskJuggler/CollisionDetector.html">TaskJuggler::CollisionDetector</a></li>
225
+
219
226
  <li><a href="../TaskJuggler/ColumnListAttribute.html">TaskJuggler::ColumnListAttribute</a></li>
220
227
 
221
228
  <li><a href="../TaskJuggler/ColumnTable.html">TaskJuggler::ColumnTable</a></li>
222
229
 
223
230
  <li><a href="../TaskJuggler/Daemon.html">TaskJuggler::Daemon</a></li>
224
231
 
232
+ <li><a href="../TaskJuggler/DataCache.html">TaskJuggler::DataCache</a></li>
233
+
234
+ <li><a href="../TaskJuggler/DataCacheEntry.html">TaskJuggler::DataCacheEntry</a></li>
235
+
225
236
  <li><a href="../TaskJuggler/DateAttribute.html">TaskJuggler::DateAttribute</a></li>
226
237
 
227
238
  <li><a href="../TaskJuggler/DefinitionListAttribute.html">TaskJuggler::DefinitionListAttribute</a></li>
@@ -328,7 +339,7 @@
328
339
 
329
340
  <li><a href="../TaskJuggler/NodeListAttribute.html">TaskJuggler::NodeListAttribute</a></li>
330
341
 
331
- <li><a href="../TaskJuggler/OnShiftCache.html">TaskJuggler::OnShiftCache</a></li>
342
+ <li><a href="../TaskJuggler/PlaceHolderCell.html">TaskJuggler::PlaceHolderCell</a></li>
332
343
 
333
344
  <li><a href="../TaskJuggler/ProcessIntercom.html">TaskJuggler::ProcessIntercom</a></li>
334
345
 
@@ -508,6 +519,10 @@
508
519
 
509
520
  <li><a href="../TaskJuggler/TextParser/StackElement.html">TaskJuggler::TextParser::StackElement</a></li>
510
521
 
522
+ <li><a href="../TaskJuggler/TextParser/State.html">TaskJuggler::TextParser::State</a></li>
523
+
524
+ <li><a href="../TaskJuggler/TextParser/StateTransition.html">TaskJuggler::TextParser::StateTransition</a></li>
525
+
511
526
  <li><a href="../TaskJuggler/TextParser/TextParserResultArray.html">TaskJuggler::TextParser::TextParserResultArray</a></li>
512
527
 
513
528
  <li><a href="../TaskJuggler/TextParser/TokenDoc.html">TaskJuggler::TextParser::TokenDoc</a></li>
@@ -615,14 +630,12 @@
615
630
 
616
631
  <div id="description">
617
632
  <p>
618
- The <a href="TextParser.html">TextParser</a> implements a regular LALR
619
- parser. But it uses a recursive rule traversor instead of the more commonly
620
- found state machine generated by yacc-like tools. Since stack depths is not
621
- really an issue with a Ruby implementation this approach has one big
622
- advantage. The syntax of the parser can be modified during parsing. This
623
- allows support for languages that can extend themself. The <a
624
- href="../TaskJuggler.html">TaskJuggler</a> syntax is such an beast.
625
- Traditional yacc generated parsers would fail with such a syntax.
633
+ The <a href="TextParser.html">TextParser</a> implements a somewhat modified
634
+ LL(1) parser. It uses a dynamically compiled state machine. Dynamically
635
+ means, that the syntax can be extended during the parse process. This
636
+ allows support for languages that can extend their syntax during the parse
637
+ process. The <a href="../TaskJuggler.html">TaskJuggler</a> syntax is such
638
+ an beast.
626
639
  </p>
627
640
  <p>
628
641
  This class is just a base class. A complete parser would derive from this
@@ -643,6 +656,15 @@ TextParser#doc, TextParser#descr, TextParser#also and TextParser#arg can be
643
656
  used.
644
657
  </p>
645
658
  <p>
659
+ In contrast to conventional LL grammars, we use a slightly improved syntax
660
+ descriptions. Repeated patterns are not described by recursive call but we
661
+ use a repeat flag for syntax rules that consists of repeatable patterns.
662
+ This removes the need for recursion elimination when compiling the state
663
+ machine and makes the syntax a lot more readable. However, it adds a bit
664
+ more complexity to the state machine. Optional patterns are described by a
665
+ rule flag, not by adding an empty pattern.
666
+ </p>
667
+ <p>
646
668
  To start parsing the input the function <a
647
669
  href="TextParser.html#method-i-parse">TextParser#parse</a> needs to be
648
670
  called with the name of the start rule.
@@ -672,19 +694,6 @@ Copyright &#169; 2006, 2007, 2008, 2009, 2010 by Chris Schlaeger
672
694
  This program is free software; you can redistribute it and/or modify it
673
695
  under the terms of version 2 of the GNU General Public License as published
674
696
  by the Free Software Foundation.
675
- </p>
676
- <hr style="height: 1px"></hr><p>
677
- encoding: UTF-8
678
- </p>
679
- <h1>StackElement.rb &#8212; The <a href="../TaskJuggler.html">TaskJuggler</a> III <a href="Project.html">Project</a> Management Software</h1>
680
- <p>
681
- Copyright &#169; 2006, 2007, 2008, 2009, 2010 by Chris Schlaeger
682
- <cs@kde.org>
683
- </p>
684
- <p>
685
- This program is free software; you can redistribute it and/or modify it
686
- under the terms of version 2 of the GNU General Public License as published
687
- by the Free Software Foundation.
688
697
  </p>
689
698
 
690
699
  </div>
@@ -759,19 +768,25 @@ Create a new <a href="TextParser.html">TextParser</a> object.
759
768
  <div class="method-source-code"
760
769
  id="new-source">
761
770
  <pre>
762
- <span class="ruby-comment cmt"># File lib/TextParser.rb, line 71</span>
763
- 71: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">initialize</span>(<span class="ruby-identifier">messageHandler</span>)
764
- 72: <span class="ruby-comment cmt"># The message handler will collect all error messages.</span>
765
- 73: <span class="ruby-ivar">@messageHandler</span> = <span class="ruby-identifier">messageHandler</span>
766
- 74: <span class="ruby-comment cmt"># This Hash will store the ruleset that the parser is operating on.</span>
767
- 75: <span class="ruby-ivar">@rules</span> = { }
768
- 76: <span class="ruby-comment cmt"># Array to hold the token types that the scanner can return.</span>
769
- 77: <span class="ruby-ivar">@variables</span> = []
770
- 78: <span class="ruby-comment cmt"># An list of token types that are not allowed in the current context.</span>
771
- 79: <span class="ruby-ivar">@badVariables</span> = []
772
- 80: <span class="ruby-comment cmt"># The currently processed rule.</span>
773
- 81: <span class="ruby-ivar">@cr</span> = <span class="ruby-keyword kw">nil</span>
774
- 82: <span class="ruby-keyword kw">end</span></pre>
771
+ <span class="ruby-comment cmt"># File lib/TextParser.rb, line 77</span>
772
+ 77: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">initialize</span>(<span class="ruby-identifier">messageHandler</span>)
773
+ 78: <span class="ruby-comment cmt"># The message handler will collect all error messages.</span>
774
+ 79: <span class="ruby-ivar">@messageHandler</span> = <span class="ruby-identifier">messageHandler</span>
775
+ 80: <span class="ruby-comment cmt"># This Hash will store the ruleset that the parser is operating on.</span>
776
+ 81: <span class="ruby-ivar">@rules</span> = { }
777
+ 82: <span class="ruby-comment cmt"># Array to hold the token types that the scanner can return.</span>
778
+ 83: <span class="ruby-ivar">@variables</span> = []
779
+ 84: <span class="ruby-comment cmt"># An list of token types that are not allowed in the current context.</span>
780
+ 85: <span class="ruby-comment cmt"># For performance reasons we use a hash with the token as key. The value</span>
781
+ 86: <span class="ruby-comment cmt"># is irrelevant.</span>
782
+ 87: <span class="ruby-ivar">@blockedVariables</span> = {}
783
+ 88: <span class="ruby-comment cmt"># The currently processed rule.</span>
784
+ 89: <span class="ruby-ivar">@cr</span> = <span class="ruby-keyword kw">nil</span>
785
+ 90:
786
+ 91: <span class="ruby-ivar">@states</span> = {}
787
+ 92: <span class="ruby-comment cmt"># The stack used by the FSM.</span>
788
+ 93: <span class="ruby-ivar">@stack</span> = <span class="ruby-keyword kw">nil</span>
789
+ 94: <span class="ruby-keyword kw">end</span></pre>
775
790
  </div>
776
791
 
777
792
  </div>
@@ -808,17 +823,17 @@ Create a new <a href="TextParser.html">TextParser</a> object.
808
823
  <div class="method-source-code"
809
824
  id="error-source">
810
825
  <pre>
811
- <span class="ruby-comment cmt"># File lib/TextParser.rb, line 197</span>
812
- 197: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">error</span>(<span class="ruby-identifier">id</span>, <span class="ruby-identifier">text</span>, <span class="ruby-identifier">sfi</span> = <span class="ruby-keyword kw">nil</span>, <span class="ruby-identifier">data</span> = <span class="ruby-keyword kw">nil</span>)
813
- 198: <span class="ruby-identifier">sfi</span> <span class="ruby-operator">||=</span> <span class="ruby-identifier">sourceFileInfo</span>
814
- 199: <span class="ruby-keyword kw">if</span> <span class="ruby-ivar">@scanner</span>
815
- 200: <span class="ruby-comment cmt"># The scanner has some more context information, so we pass the error</span>
816
- 201: <span class="ruby-comment cmt"># on to the TextScanner.</span>
817
- 202: <span class="ruby-ivar">@scanner</span>.<span class="ruby-identifier">error</span>(<span class="ruby-identifier">id</span>, <span class="ruby-identifier">text</span>, <span class="ruby-identifier">sfi</span>, <span class="ruby-identifier">data</span>)
818
- 203: <span class="ruby-keyword kw">else</span>
819
- 204: <span class="ruby-ivar">@messageHandler</span>.<span class="ruby-identifier">error</span>(<span class="ruby-identifier">id</span>, <span class="ruby-identifier">text</span>, <span class="ruby-identifier">sfi</span>, <span class="ruby-identifier">data</span>)
820
- 205: <span class="ruby-keyword kw">end</span>
821
- 206: <span class="ruby-keyword kw">end</span></pre>
826
+ <span class="ruby-comment cmt"># File lib/TextParser.rb, line 219</span>
827
+ 219: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">error</span>(<span class="ruby-identifier">id</span>, <span class="ruby-identifier">text</span>, <span class="ruby-identifier">sfi</span> = <span class="ruby-keyword kw">nil</span>, <span class="ruby-identifier">data</span> = <span class="ruby-keyword kw">nil</span>)
828
+ 220: <span class="ruby-identifier">sfi</span> <span class="ruby-operator">||=</span> <span class="ruby-identifier">sourceFileInfo</span>
829
+ 221: <span class="ruby-keyword kw">if</span> <span class="ruby-ivar">@scanner</span>
830
+ 222: <span class="ruby-comment cmt"># The scanner has some more context information, so we pass the error</span>
831
+ 223: <span class="ruby-comment cmt"># on to the TextScanner.</span>
832
+ 224: <span class="ruby-ivar">@scanner</span>.<span class="ruby-identifier">error</span>(<span class="ruby-identifier">id</span>, <span class="ruby-identifier">text</span>, <span class="ruby-identifier">sfi</span>, <span class="ruby-identifier">data</span>)
833
+ 225: <span class="ruby-keyword kw">else</span>
834
+ 226: <span class="ruby-ivar">@messageHandler</span>.<span class="ruby-identifier">error</span>(<span class="ruby-identifier">id</span>, <span class="ruby-identifier">text</span>, <span class="ruby-identifier">sfi</span>, <span class="ruby-identifier">data</span>)
835
+ 227: <span class="ruby-keyword kw">end</span>
836
+ 228: <span class="ruby-keyword kw">end</span></pre>
822
837
  </div>
823
838
 
824
839
  </div>
@@ -852,17 +867,17 @@ rules.
852
867
  <div class="method-source-code"
853
868
  id="init-ules-source">
854
869
  <pre>
855
- <span class="ruby-comment cmt"># File lib/TextParser.rb, line 94</span>
856
- 94: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">initRules</span>
857
- 95: <span class="ruby-identifier">methods</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">m</span><span class="ruby-operator">|</span>
858
- 96: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">m</span>[<span class="ruby-value">0</span>, <span class="ruby-value">5</span>] <span class="ruby-operator">==</span> <span class="ruby-value str">'rule_'</span>
859
- 97: <span class="ruby-comment cmt"># Create a new rule with the suffix of the function name as name.</span>
860
- 98: <span class="ruby-identifier">newRule</span>(<span class="ruby-identifier">m</span>[<span class="ruby-value">5</span><span class="ruby-operator">..</span><span class="ruby-value">1</span>])
861
- 99: <span class="ruby-comment cmt"># Call the function.</span>
862
- 100: <span class="ruby-identifier">send</span>(<span class="ruby-identifier">m</span>)
863
- 101: <span class="ruby-keyword kw">end</span>
864
- 102: <span class="ruby-keyword kw">end</span>
865
- 103: <span class="ruby-keyword kw">end</span></pre>
870
+ <span class="ruby-comment cmt"># File lib/TextParser.rb, line 111</span>
871
+ 111: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">initRules</span>
872
+ 112: <span class="ruby-identifier">methods</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">m</span><span class="ruby-operator">|</span>
873
+ 113: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">m</span>[<span class="ruby-value">0</span>, <span class="ruby-value">5</span>] <span class="ruby-operator">==</span> <span class="ruby-value str">'rule_'</span>
874
+ 114: <span class="ruby-comment cmt"># Create a new rule with the suffix of the function name as name.</span>
875
+ 115: <span class="ruby-identifier">newRule</span>(<span class="ruby-identifier">m</span>[<span class="ruby-value">5</span><span class="ruby-operator">..</span><span class="ruby-value">1</span>])
876
+ 116: <span class="ruby-comment cmt"># Call the function.</span>
877
+ 117: <span class="ruby-identifier">send</span>(<span class="ruby-identifier">m</span>)
878
+ 118: <span class="ruby-keyword kw">end</span>
879
+ 119: <span class="ruby-keyword kw">end</span>
880
+ 120: <span class="ruby-keyword kw">end</span></pre>
866
881
  </div>
867
882
 
868
883
  </div>
@@ -896,52 +911,18 @@ Limit the allowed tokens of the scanner to the subset passed by the
896
911
  <div class="method-source-code"
897
912
  id="limit-oken-et-source">
898
913
  <pre>
899
- <span class="ruby-comment cmt"># File lib/TextParser.rb, line 86</span>
900
- 86: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">limitTokenSet</span>(<span class="ruby-identifier">tokenSet</span>)
901
- 87: <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">tokenSet</span>
902
- 88:
903
- 89: <span class="ruby-ivar">@badVariables</span> = <span class="ruby-ivar">@variables</span>.<span class="ruby-identifier">dup</span>
904
- 90: <span class="ruby-ivar">@badVariables</span>.<span class="ruby-identifier">delete_if</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">v</span><span class="ruby-operator">|</span> <span class="ruby-identifier">tokenSet</span>.<span class="ruby-identifier">include?</span>(<span class="ruby-identifier">v</span>) }
905
- 91: <span class="ruby-keyword kw">end</span></pre>
906
- </div>
907
-
908
- </div>
909
-
910
-
911
-
912
-
913
- </div>
914
-
915
-
916
- <div id="matching-ules-method" class="method-detail ">
917
- <a name="method-i-matchingRules"></a>
918
-
919
- <div class="method-heading">
920
-
921
- <span class="method-name">matchingRules</span><span
922
- class="method-args">(keyword)</span>
923
- <span class="method-click-advice">click to toggle source</span>
924
-
925
- </div>
926
-
927
- <div class="method-description">
928
-
929
-
930
-
931
-
932
-
933
- <div class="method-source-code"
934
- id="matching-ules-source">
935
- <pre>
936
- <span class="ruby-comment cmt"># File lib/TextParser.rb, line 188</span>
937
- 188: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">matchingRules</span>(<span class="ruby-identifier">keyword</span>)
938
- 189: <span class="ruby-identifier">matches</span> = []
939
- 190: <span class="ruby-ivar">@rules</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">name</span>, <span class="ruby-identifier">rule</span><span class="ruby-operator">|</span>
940
- 191: <span class="ruby-identifier">patIdx</span> = <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">matchingPatternIndex</span>(<span class="ruby-value str">'_'</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">keyword</span>)
941
- 192: <span class="ruby-identifier">matches</span> <span class="ruby-operator">&lt;&lt;</span> [ <span class="ruby-identifier">rule</span>, <span class="ruby-identifier">patIdx</span> ] <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">patIdx</span>
942
- 193: <span class="ruby-keyword kw">end</span>
943
- 194: <span class="ruby-identifier">matches</span>
944
- 195: <span class="ruby-keyword kw">end</span></pre>
914
+ <span class="ruby-comment cmt"># File lib/TextParser.rb, line 98</span>
915
+ 98: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">limitTokenSet</span>(<span class="ruby-identifier">tokenSet</span>)
916
+ 99: <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">tokenSet</span>
917
+ 100:
918
+ 101: <span class="ruby-comment cmt"># Create a copy of all supported variables.</span>
919
+ 102: <span class="ruby-identifier">blockedVariables</span> = <span class="ruby-ivar">@variables</span>.<span class="ruby-identifier">dup</span>
920
+ 103: <span class="ruby-comment cmt"># Then delete all that are in the limited set.</span>
921
+ 104: <span class="ruby-identifier">blockedVariables</span>.<span class="ruby-identifier">delete_if</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">v</span><span class="ruby-operator">|</span> <span class="ruby-identifier">tokenSet</span>.<span class="ruby-identifier">include?</span>(<span class="ruby-identifier">v</span>) }
922
+ 105: <span class="ruby-comment cmt"># And convert the list into a Hash for faster lookups.</span>
923
+ 106: <span class="ruby-ivar">@blockedVariables</span> = {}
924
+ 107: <span class="ruby-identifier">blockedVariables</span>.<span class="ruby-identifier">each</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">v</span><span class="ruby-operator">|</span> <span class="ruby-ivar">@blockedVariables</span>[<span class="ruby-identifier">v</span>] = <span class="ruby-keyword kw">true</span> }
925
+ 108: <span class="ruby-keyword kw">end</span></pre>
945
926
  </div>
946
927
 
947
928
  </div>
@@ -979,19 +960,21 @@ then implicitely operate on the most recently added rule.
979
960
  <div class="method-source-code"
980
961
  id="new-ule-source">
981
962
  <pre>
982
- <span class="ruby-comment cmt"># File lib/TextParser.rb, line 110</span>
983
- 110: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">newRule</span>(<span class="ruby-identifier">name</span>)
984
- 111: <span class="ruby-identifier">raise</span> <span class="ruby-node">&quot;Fatal Error: Rule #{name} already exists&quot;</span> <span class="ruby-keyword kw">if</span> <span class="ruby-ivar">@rules</span>.<span class="ruby-identifier">has_key?</span>(<span class="ruby-identifier">name</span>)
985
- 112:
986
- 113: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">block_given?</span>
987
- 114: <span class="ruby-identifier">saveCr</span> = <span class="ruby-ivar">@cr</span>
988
- 115: <span class="ruby-ivar">@rules</span>[<span class="ruby-identifier">name</span>] = <span class="ruby-ivar">@cr</span> = <span class="ruby-constant">TextParser</span><span class="ruby-operator">::</span><span class="ruby-constant">Rule</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">name</span>)
989
- 116: <span class="ruby-keyword kw">yield</span>
990
- 117: <span class="ruby-ivar">@cr</span> = <span class="ruby-identifier">saveCr</span>
991
- 118: <span class="ruby-keyword kw">else</span>
992
- 119: <span class="ruby-ivar">@rules</span>[<span class="ruby-identifier">name</span>] = <span class="ruby-ivar">@cr</span> = <span class="ruby-constant">TextParser</span><span class="ruby-operator">::</span><span class="ruby-constant">Rule</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">name</span>)
993
- 120: <span class="ruby-keyword kw">end</span>
994
- 121: <span class="ruby-keyword kw">end</span></pre>
963
+ <span class="ruby-comment cmt"># File lib/TextParser.rb, line 127</span>
964
+ 127: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">newRule</span>(<span class="ruby-identifier">name</span>)
965
+ 128: <span class="ruby-comment cmt"># Use a symbol instead of a String.</span>
966
+ 129: <span class="ruby-identifier">name</span> = <span class="ruby-identifier">name</span>.<span class="ruby-identifier">intern</span>
967
+ 130: <span class="ruby-identifier">raise</span> <span class="ruby-node">&quot;Fatal Error: Rule #{name} already exists&quot;</span> <span class="ruby-keyword kw">if</span> <span class="ruby-ivar">@rules</span>.<span class="ruby-identifier">has_key?</span>(<span class="ruby-identifier">name</span>)
968
+ 131:
969
+ 132: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">block_given?</span>
970
+ 133: <span class="ruby-identifier">saveCr</span> = <span class="ruby-ivar">@cr</span>
971
+ 134: <span class="ruby-ivar">@rules</span>[<span class="ruby-identifier">name</span>] = <span class="ruby-ivar">@cr</span> = <span class="ruby-constant">TextParser</span><span class="ruby-operator">::</span><span class="ruby-constant">Rule</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">name</span>)
972
+ 135: <span class="ruby-keyword kw">yield</span>
973
+ 136: <span class="ruby-ivar">@cr</span> = <span class="ruby-identifier">saveCr</span>
974
+ 137: <span class="ruby-keyword kw">else</span>
975
+ 138: <span class="ruby-ivar">@rules</span>[<span class="ruby-identifier">name</span>] = <span class="ruby-ivar">@cr</span> = <span class="ruby-constant">TextParser</span><span class="ruby-operator">::</span><span class="ruby-constant">Rule</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">name</span>)
976
+ 139: <span class="ruby-keyword kw">end</span>
977
+ 140: <span class="ruby-keyword kw">end</span></pre>
995
978
  </div>
996
979
 
997
980
  </div>
@@ -1025,10 +1008,10 @@ elements.
1025
1008
  <div class="method-source-code"
1026
1009
  id="optional-source">
1027
1010
  <pre>
1028
- <span class="ruby-comment cmt"># File lib/TextParser.rb, line 140</span>
1029
- 140: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">optional</span>
1030
- 141: <span class="ruby-ivar">@cr</span>.<span class="ruby-identifier">setOptional</span>
1031
- 142: <span class="ruby-keyword kw">end</span></pre>
1011
+ <span class="ruby-comment cmt"># File lib/TextParser.rb, line 159</span>
1012
+ 159: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">optional</span>
1013
+ 160: <span class="ruby-ivar">@cr</span>.<span class="ruby-identifier">setOptional</span>
1014
+ 161: <span class="ruby-keyword kw">end</span></pre>
1032
1015
  </div>
1033
1016
 
1034
1017
  </div>
@@ -1064,22 +1047,21 @@ an error, the result is false.
1064
1047
  <div class="method-source-code"
1065
1048
  id="parse-source">
1066
1049
  <pre>
1067
- <span class="ruby-comment cmt"># File lib/TextParser.rb, line 164</span>
1068
- 164: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">parse</span>(<span class="ruby-identifier">ruleName</span>)
1069
- 165: <span class="ruby-ivar">@stack</span> = []
1070
- 166: <span class="ruby-identifier">@@expectedTokens</span> = []
1071
- 167: <span class="ruby-identifier">updateParserTables</span>
1072
- 168: <span class="ruby-keyword kw">begin</span>
1073
- 169: <span class="ruby-identifier">result</span> = <span class="ruby-identifier">parseRuleR</span>(<span class="ruby-ivar">@rules</span>[<span class="ruby-identifier">ruleName</span>])
1074
- 170: <span class="ruby-keyword kw">rescue</span> <span class="ruby-constant">TjException</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">msg</span>
1075
- 171: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">msg</span>.<span class="ruby-identifier">message</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-operator">!</span><span class="ruby-identifier">msg</span>.<span class="ruby-identifier">message</span>.<span class="ruby-identifier">empty?</span>
1076
- 172: <span class="ruby-ivar">@messageHandler</span>.<span class="ruby-identifier">critical</span>(<span class="ruby-value str">'parse'</span>, <span class="ruby-identifier">msg</span>.<span class="ruby-identifier">message</span>)
1077
- 173: <span class="ruby-keyword kw">end</span>
1078
- 174: <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">false</span>
1079
- 175: <span class="ruby-keyword kw">end</span>
1080
- 176:
1081
- 177: <span class="ruby-identifier">result</span>
1082
- 178: <span class="ruby-keyword kw">end</span></pre>
1050
+ <span class="ruby-comment cmt"># File lib/TextParser.rb, line 196</span>
1051
+ 196: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">parse</span>(<span class="ruby-identifier">ruleName</span>)
1052
+ 197: <span class="ruby-ivar">@stack</span> = []
1053
+ 198: <span class="ruby-identifier">@@expectedTokens</span> = []
1054
+ 199: <span class="ruby-keyword kw">begin</span>
1055
+ 200: <span class="ruby-identifier">result</span> = <span class="ruby-identifier">parseFSM</span>(<span class="ruby-ivar">@rules</span>[<span class="ruby-identifier">ruleName</span>])
1056
+ 201: <span class="ruby-keyword kw">rescue</span> <span class="ruby-constant">TjException</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">msg</span>
1057
+ 202: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">msg</span>.<span class="ruby-identifier">message</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-operator">!</span><span class="ruby-identifier">msg</span>.<span class="ruby-identifier">message</span>.<span class="ruby-identifier">empty?</span>
1058
+ 203: <span class="ruby-ivar">@messageHandler</span>.<span class="ruby-identifier">critical</span>(<span class="ruby-value str">'parse'</span>, <span class="ruby-identifier">msg</span>.<span class="ruby-identifier">message</span>)
1059
+ 204: <span class="ruby-keyword kw">end</span>
1060
+ 205: <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">false</span>
1061
+ 206: <span class="ruby-keyword kw">end</span>
1062
+ 207:
1063
+ 208: <span class="ruby-identifier">result</span>
1064
+ 209: <span class="ruby-keyword kw">end</span></pre>
1083
1065
  </div>
1084
1066
 
1085
1067
  </div>
@@ -1133,10 +1115,10 @@ completed the processing of this rule.
1133
1115
  <div class="method-source-code"
1134
1116
  id="pattern-source">
1135
1117
  <pre>
1136
- <span class="ruby-comment cmt"># File lib/TextParser.rb, line 134</span>
1137
- 134: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">pattern</span>(<span class="ruby-identifier">tokens</span>, <span class="ruby-identifier">func</span> = <span class="ruby-keyword kw">nil</span>)
1138
- 135: <span class="ruby-ivar">@cr</span>.<span class="ruby-identifier">addPattern</span>(<span class="ruby-constant">TextParser</span><span class="ruby-operator">::</span><span class="ruby-constant">Pattern</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">tokens</span>, <span class="ruby-identifier">func</span>))
1139
- 136: <span class="ruby-keyword kw">end</span></pre>
1118
+ <span class="ruby-comment cmt"># File lib/TextParser.rb, line 153</span>
1119
+ 153: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">pattern</span>(<span class="ruby-identifier">tokens</span>, <span class="ruby-identifier">func</span> = <span class="ruby-keyword kw">nil</span>)
1120
+ 154: <span class="ruby-ivar">@cr</span>.<span class="ruby-identifier">addPattern</span>(<span class="ruby-constant">TextParser</span><span class="ruby-operator">::</span><span class="ruby-constant">Pattern</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">tokens</span>, <span class="ruby-identifier">func</span>))
1121
+ 155: <span class="ruby-keyword kw">end</span></pre>
1140
1122
  </div>
1141
1123
 
1142
1124
  </div>
@@ -1170,10 +1152,10 @@ elements.
1170
1152
  <div class="method-source-code"
1171
1153
  id="repeatable-source">
1172
1154
  <pre>
1173
- <span class="ruby-comment cmt"># File lib/TextParser.rb, line 146</span>
1174
- 146: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">repeatable</span>
1175
- 147: <span class="ruby-ivar">@cr</span>.<span class="ruby-identifier">setRepeatable</span>
1176
- 148: <span class="ruby-keyword kw">end</span></pre>
1155
+ <span class="ruby-comment cmt"># File lib/TextParser.rb, line 165</span>
1156
+ 165: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">repeatable</span>
1157
+ 166: <span class="ruby-ivar">@cr</span>.<span class="ruby-identifier">setRepeatable</span>
1158
+ 167: <span class="ruby-keyword kw">end</span></pre>
1177
1159
  </div>
1178
1160
 
1179
1161
  </div>
@@ -1209,11 +1191,11 @@ nil if we don&#8217;t have a current position.
1209
1191
  <div class="method-source-code"
1210
1192
  id="source-ile-nfo-source">
1211
1193
  <pre>
1212
- <span class="ruby-comment cmt"># File lib/TextParser.rb, line 183</span>
1213
- 183: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">sourceFileInfo</span>
1214
- 184: <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">nil</span> <span class="ruby-keyword kw">if</span> <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">nil?</span> <span class="ruby-operator">||</span> <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">empty?</span>
1215
- 185: <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">last</span>.<span class="ruby-identifier">sourceFileInfo</span>[<span class="ruby-value">0</span>]
1216
- 186: <span class="ruby-keyword kw">end</span></pre>
1194
+ <span class="ruby-comment cmt"># File lib/TextParser.rb, line 214</span>
1195
+ 214: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">sourceFileInfo</span>
1196
+ 215: <span class="ruby-keyword kw">return</span> <span class="ruby-ivar">@scanner</span>.<span class="ruby-identifier">sourceFileInfo</span> <span class="ruby-keyword kw">if</span> <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">nil?</span> <span class="ruby-operator">||</span> <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">length</span> <span class="ruby-operator">&lt;=</span> <span class="ruby-value">1</span>
1197
+ 216: <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">last</span>.<span class="ruby-identifier">firstSourceFileInfo</span>
1198
+ 217: <span class="ruby-keyword kw">end</span></pre>
1217
1199
  </div>
1218
1200
 
1219
1201
  </div>
@@ -1240,7 +1222,9 @@ nil if we don&#8217;t have a current position.
1240
1222
  <p>
1241
1223
  This function needs to be called whenever new rules or patterns have been
1242
1224
  added and before the next call to <a
1243
- href="TextParser.html#method-i-parse">TextParser#parse</a>.
1225
+ href="TextParser.html#method-i-parse">TextParser#parse</a>. It&#8217;s
1226
+ perfectly ok to call this function from within a parse() call as long as
1227
+ the states that are currently on the stack have not been modified.
1244
1228
  </p>
1245
1229
 
1246
1230
 
@@ -1248,14 +1232,25 @@ href="TextParser.html#method-i-parse">TextParser#parse</a>.
1248
1232
  <div class="method-source-code"
1249
1233
  id="update-arser-ables-source">
1250
1234
  <pre>
1251
- <span class="ruby-comment cmt"># File lib/TextParser.rb, line 152</span>
1252
- 152: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">updateParserTables</span>
1253
- 153: <span class="ruby-ivar">@rules</span>.<span class="ruby-identifier">each_value</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">rule</span><span class="ruby-operator">|</span> <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">transitions</span> = {} }
1254
- 154: <span class="ruby-ivar">@rules</span>.<span class="ruby-identifier">each_value</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">rule</span><span class="ruby-operator">|</span>
1255
- 155: <span class="ruby-identifier">getTransitions</span>(<span class="ruby-identifier">rule</span>)
1256
- 156: <span class="ruby-identifier">checkRule</span>(<span class="ruby-identifier">rule</span>)
1257
- 157: <span class="ruby-keyword kw">end</span>
1258
- 158: <span class="ruby-keyword kw">end</span></pre>
1235
+ <span class="ruby-comment cmt"># File lib/TextParser.rb, line 173</span>
1236
+ 173: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">updateParserTables</span>
1237
+ 174: <span class="ruby-identifier">saveFsmStack</span>
1238
+ 175: <span class="ruby-comment cmt"># Invalidate some cached data.</span>
1239
+ 176: <span class="ruby-ivar">@rules</span>.<span class="ruby-identifier">each_value</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">rule</span><span class="ruby-operator">|</span> <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">flushCache</span> }
1240
+ 177: <span class="ruby-ivar">@states</span> = {}
1241
+ 178: <span class="ruby-comment cmt"># Generate the parser states for all patterns of all rules.</span>
1242
+ 179: <span class="ruby-ivar">@rules</span>.<span class="ruby-identifier">each_value</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">rule</span><span class="ruby-operator">|</span>
1243
+ 180: <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">generateStates</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">s</span><span class="ruby-operator">|</span>
1244
+ 181: <span class="ruby-ivar">@states</span>[[ <span class="ruby-identifier">s</span>.<span class="ruby-identifier">rule</span>, <span class="ruby-identifier">s</span>.<span class="ruby-identifier">pattern</span>, <span class="ruby-identifier">s</span>.<span class="ruby-identifier">index</span> ]] = <span class="ruby-identifier">s</span>
1245
+ 182: <span class="ruby-keyword kw">end</span>
1246
+ 183: <span class="ruby-identifier">checkRule</span>(<span class="ruby-identifier">rule</span>)
1247
+ 184: <span class="ruby-keyword kw">end</span>
1248
+ 185: <span class="ruby-comment cmt"># Compute the transitions between the generated states.</span>
1249
+ 186: <span class="ruby-ivar">@states</span>.<span class="ruby-identifier">each_value</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">state</span><span class="ruby-operator">|</span>
1250
+ 187: <span class="ruby-identifier">state</span>.<span class="ruby-identifier">addTransitions</span>(<span class="ruby-ivar">@states</span>, <span class="ruby-ivar">@rules</span>)
1251
+ 188: <span class="ruby-keyword kw">end</span>
1252
+ 189: <span class="ruby-identifier">restoreFsmStack</span>
1253
+ 190: <span class="ruby-keyword kw">end</span></pre>
1259
1254
  </div>
1260
1255
 
1261
1256
  </div>
@@ -1286,17 +1281,17 @@ href="TextParser.html#method-i-parse">TextParser#parse</a>.
1286
1281
  <div class="method-source-code"
1287
1282
  id="warning-source">
1288
1283
  <pre>
1289
- <span class="ruby-comment cmt"># File lib/TextParser.rb, line 208</span>
1290
- 208: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">warning</span>(<span class="ruby-identifier">id</span>, <span class="ruby-identifier">text</span>, <span class="ruby-identifier">sfi</span> = <span class="ruby-keyword kw">nil</span>, <span class="ruby-identifier">data</span> = <span class="ruby-keyword kw">nil</span>)
1291
- 209: <span class="ruby-identifier">sfi</span> <span class="ruby-operator">||=</span> <span class="ruby-identifier">sourceFileInfo</span>
1292
- 210: <span class="ruby-keyword kw">if</span> <span class="ruby-ivar">@scanner</span>
1293
- 211: <span class="ruby-comment cmt"># The scanner has some more context information, so we pass the</span>
1294
- 212: <span class="ruby-comment cmt"># warning on to the TextScanner.</span>
1295
- 213: <span class="ruby-ivar">@scanner</span>.<span class="ruby-identifier">warning</span>(<span class="ruby-identifier">id</span>, <span class="ruby-identifier">text</span>, <span class="ruby-identifier">sfi</span>, <span class="ruby-identifier">data</span>)
1296
- 214: <span class="ruby-keyword kw">else</span>
1297
- 215: <span class="ruby-ivar">@messageHandler</span>.<span class="ruby-identifier">warning</span>(<span class="ruby-identifier">id</span>, <span class="ruby-identifier">text</span>, <span class="ruby-identifier">sfi</span>, <span class="ruby-identifier">data</span>)
1298
- 216: <span class="ruby-keyword kw">end</span>
1299
- 217: <span class="ruby-keyword kw">end</span></pre>
1284
+ <span class="ruby-comment cmt"># File lib/TextParser.rb, line 230</span>
1285
+ 230: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">warning</span>(<span class="ruby-identifier">id</span>, <span class="ruby-identifier">text</span>, <span class="ruby-identifier">sfi</span> = <span class="ruby-keyword kw">nil</span>, <span class="ruby-identifier">data</span> = <span class="ruby-keyword kw">nil</span>)
1286
+ 231: <span class="ruby-identifier">sfi</span> <span class="ruby-operator">||=</span> <span class="ruby-identifier">sourceFileInfo</span>
1287
+ 232: <span class="ruby-keyword kw">if</span> <span class="ruby-ivar">@scanner</span>
1288
+ 233: <span class="ruby-comment cmt"># The scanner has some more context information, so we pass the</span>
1289
+ 234: <span class="ruby-comment cmt"># warning on to the TextScanner.</span>
1290
+ 235: <span class="ruby-ivar">@scanner</span>.<span class="ruby-identifier">warning</span>(<span class="ruby-identifier">id</span>, <span class="ruby-identifier">text</span>, <span class="ruby-identifier">sfi</span>, <span class="ruby-identifier">data</span>)
1291
+ 236: <span class="ruby-keyword kw">else</span>
1292
+ 237: <span class="ruby-ivar">@messageHandler</span>.<span class="ruby-identifier">warning</span>(<span class="ruby-identifier">id</span>, <span class="ruby-identifier">text</span>, <span class="ruby-identifier">sfi</span>, <span class="ruby-identifier">data</span>)
1293
+ 238: <span class="ruby-keyword kw">end</span>
1294
+ 239: <span class="ruby-keyword kw">end</span></pre>
1300
1295
  </div>
1301
1296
 
1302
1297
  </div>
@@ -1333,30 +1328,28 @@ href="TextParser.html#method-i-parse">TextParser#parse</a>.
1333
1328
  <div class="method-source-code"
1334
1329
  id="check-ule-source">
1335
1330
  <pre>
1336
- <span class="ruby-comment cmt"># File lib/TextParser.rb, line 277</span>
1337
- 277: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">checkRule</span>(<span class="ruby-identifier">rule</span>)
1338
- 278: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">patterns</span>.<span class="ruby-identifier">empty?</span>
1339
- 279: <span class="ruby-identifier">raise</span> <span class="ruby-node">&quot;Rule #{rule.name} must have at least one pattern&quot;</span>
1340
- 280: <span class="ruby-keyword kw">end</span>
1341
- 281:
1342
- 282: <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">patterns</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">pat</span><span class="ruby-operator">|</span>
1343
- 283: <span class="ruby-identifier">pat</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">tok</span><span class="ruby-operator">|</span>
1344
- 284: <span class="ruby-identifier">type</span> = <span class="ruby-identifier">tok</span>[<span class="ruby-value">0</span>]
1345
- 285: <span class="ruby-identifier">token</span> = <span class="ruby-identifier">tok</span>[<span class="ruby-value">1</span><span class="ruby-operator">..</span><span class="ruby-value">1</span>]
1346
- 286: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">type</span> <span class="ruby-operator">==</span> <span class="ruby-value">$$</span>
1347
- 287: <span class="ruby-keyword kw">if</span> <span class="ruby-ivar">@variables</span>.<span class="ruby-identifier">index</span>(<span class="ruby-identifier">token</span>).<span class="ruby-identifier">nil?</span>
1348
- 288: <span class="ruby-identifier">error</span>(<span class="ruby-value str">'unsupported_token'</span>,
1349
- 289: <span class="ruby-node">&quot;The token #{token} is not supported here.&quot;</span>, <span class="ruby-identifier">token</span>[<span class="ruby-value">2</span>])
1350
- 290: <span class="ruby-keyword kw">end</span>
1351
- 291: <span class="ruby-keyword kw">elsif</span> <span class="ruby-identifier">type</span> <span class="ruby-operator">==</span> <span class="ruby-value">!!</span>
1352
- 292: <span class="ruby-keyword kw">if</span> <span class="ruby-ivar">@rules</span>[<span class="ruby-identifier">token</span>].<span class="ruby-identifier">nil?</span>
1353
- 293: <span class="ruby-identifier">raise</span> <span class="ruby-node">&quot;Fatal Error: Reference to unknown rule #{token} in &quot;</span> <span class="ruby-operator">+</span>
1354
- 294: <span class="ruby-node">&quot;pattern '#{pat}' of rule #{rule.name}&quot;</span>
1355
- 295: <span class="ruby-keyword kw">end</span>
1356
- 296: <span class="ruby-keyword kw">end</span>
1357
- 297: <span class="ruby-keyword kw">end</span>
1358
- 298: <span class="ruby-keyword kw">end</span>
1359
- 299: <span class="ruby-keyword kw">end</span></pre>
1331
+ <span class="ruby-comment cmt"># File lib/TextParser.rb, line 243</span>
1332
+ 243: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">checkRule</span>(<span class="ruby-identifier">rule</span>)
1333
+ 244: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">patterns</span>.<span class="ruby-identifier">empty?</span>
1334
+ 245: <span class="ruby-identifier">raise</span> <span class="ruby-node">&quot;Rule #{rule.name} must have at least one pattern&quot;</span>
1335
+ 246: <span class="ruby-keyword kw">end</span>
1336
+ 247:
1337
+ 248: <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">patterns</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">pat</span><span class="ruby-operator">|</span>
1338
+ 249: <span class="ruby-identifier">pat</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">type</span>, <span class="ruby-identifier">name</span><span class="ruby-operator">|</span>
1339
+ 250: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:variable</span>
1340
+ 251: <span class="ruby-keyword kw">if</span> <span class="ruby-ivar">@variables</span>.<span class="ruby-identifier">index</span>(<span class="ruby-identifier">name</span>).<span class="ruby-identifier">nil?</span>
1341
+ 252: <span class="ruby-identifier">error</span>(<span class="ruby-value str">'unsupported_token'</span>,
1342
+ 253: <span class="ruby-node">&quot;The token #{name} is not supported here.&quot;</span>)
1343
+ 254: <span class="ruby-keyword kw">end</span>
1344
+ 255: <span class="ruby-keyword kw">elsif</span> <span class="ruby-identifier">type</span> <span class="ruby-operator">==</span> <span class="ruby-value">:reference</span>
1345
+ 256: <span class="ruby-keyword kw">if</span> <span class="ruby-ivar">@rules</span>[<span class="ruby-identifier">name</span>].<span class="ruby-identifier">nil?</span>
1346
+ 257: <span class="ruby-identifier">raise</span> <span class="ruby-node">&quot;Fatal Error: Reference to unknown rule #{name} in &quot;</span> <span class="ruby-operator">+</span>
1347
+ 258: <span class="ruby-node">&quot;pattern '#{pat}' of rule #{rule.name}&quot;</span>
1348
+ 259: <span class="ruby-keyword kw">end</span>
1349
+ 260: <span class="ruby-keyword kw">end</span>
1350
+ 261: <span class="ruby-keyword kw">end</span>
1351
+ 262: <span class="ruby-keyword kw">end</span>
1352
+ 263: <span class="ruby-keyword kw">end</span></pre>
1360
1353
  </div>
1361
1354
 
1362
1355
  </div>
@@ -1367,13 +1360,13 @@ href="TextParser.html#method-i-parse">TextParser#parse</a>.
1367
1360
  </div>
1368
1361
 
1369
1362
 
1370
- <div id="find-attern-method" class="method-detail ">
1371
- <a name="method-i-findPattern"></a>
1363
+ <div id="dump-tack-method" class="method-detail ">
1364
+ <a name="method-i-dumpStack"></a>
1372
1365
 
1373
1366
  <div class="method-heading">
1374
1367
 
1375
- <span class="method-name">findPattern</span><span
1376
- class="method-args">(rule, token, repeatMode)</span>
1368
+ <span class="method-name">dumpStack</span><span
1369
+ class="method-args">()</span>
1377
1370
  <span class="method-click-advice">click to toggle source</span>
1378
1371
 
1379
1372
  </div>
@@ -1385,57 +1378,32 @@ href="TextParser.html#method-i-parse">TextParser#parse</a>.
1385
1378
 
1386
1379
 
1387
1380
  <div class="method-source-code"
1388
- id="find-attern-source">
1381
+ id="dump-tack-source">
1389
1382
  <pre>
1390
- <span class="ruby-comment cmt"># File lib/TextParser.rb, line 537</span>
1391
- 537: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">findPattern</span>(<span class="ruby-identifier">rule</span>, <span class="ruby-identifier">token</span>, <span class="ruby-identifier">repeatMode</span>)
1392
- 538: <span class="ruby-comment cmt"># The scanner cannot differentiate between keywords and identifiers. So</span>
1393
- 539: <span class="ruby-comment cmt"># whenever an identifier is returned we have to see if we have a</span>
1394
- 540: <span class="ruby-comment cmt"># matching keyword first. If none is found, then look for normal</span>
1395
- 541: <span class="ruby-comment cmt"># identifiers.</span>
1396
- 542: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">token</span>[<span class="ruby-value">0</span>] <span class="ruby-operator">==</span> <span class="ruby-value str">'ID'</span>
1397
- 543: <span class="ruby-keyword kw">if</span> (<span class="ruby-identifier">patIdx</span> = <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">matchingPatternIndex</span>(<span class="ruby-value str">'_'</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">token</span>[<span class="ruby-value">1</span>])).<span class="ruby-identifier">nil?</span>
1398
- 544: <span class="ruby-identifier">patIdx</span> = <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">matchingPatternIndex</span>(<span class="ruby-value str">&quot;$ID&quot;</span>)
1399
- 545: <span class="ruby-keyword kw">end</span>
1400
- 546: <span class="ruby-keyword kw">elsif</span> <span class="ruby-identifier">token</span>[<span class="ruby-value">0</span>] <span class="ruby-operator">==</span> <span class="ruby-value str">'LITERAL'</span>
1401
- 547: <span class="ruby-identifier">patIdx</span> = <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">matchingPatternIndex</span>(<span class="ruby-value str">'_'</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">token</span>[<span class="ruby-value">1</span>])
1402
- 548: <span class="ruby-keyword kw">elsif</span> <span class="ruby-identifier">token</span>[<span class="ruby-value">0</span>] <span class="ruby-operator">==</span> <span class="ruby-keyword kw">false</span>
1403
- 549: <span class="ruby-identifier">patIdx</span> = <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">matchingPatternIndex</span>(<span class="ruby-value str">'.'</span>)
1404
- 550: <span class="ruby-keyword kw">else</span>
1405
- 551: <span class="ruby-identifier">patIdx</span> = <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">matchingPatternIndex</span>(<span class="ruby-value str">'$'</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">token</span>[<span class="ruby-value">0</span>])
1406
- 552: <span class="ruby-keyword kw">end</span>
1407
- 553:
1408
- 554: <span class="ruby-comment cmt"># If no matching pattern is found for the token we have to check if the</span>
1409
- 555: <span class="ruby-comment cmt"># rule is optional or we are in repeat mode. If this is the case, return</span>
1410
- 556: <span class="ruby-comment cmt"># the token back to the scanner. Otherwise, we have found a token we</span>
1411
- 557: <span class="ruby-comment cmt"># cannot handle at this point.</span>
1412
- 558: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">patIdx</span>.<span class="ruby-identifier">nil?</span>
1413
- 559: <span class="ruby-comment cmt"># Append the list of expected tokens to the @@expectedToken array.</span>
1414
- 560: <span class="ruby-comment cmt"># This may be used in a later rule to provide more details when an</span>
1415
- 561: <span class="ruby-comment cmt"># error occured.</span>
1416
- 562: <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">transitions</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">transition</span><span class="ruby-operator">|</span>
1417
- 563: <span class="ruby-identifier">keys</span> = <span class="ruby-identifier">transition</span>.<span class="ruby-identifier">keys</span>
1418
- 564: <span class="ruby-identifier">keys</span>.<span class="ruby-identifier">collect!</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">key</span><span class="ruby-operator">|</span> <span class="ruby-identifier">key</span>[<span class="ruby-value">1</span><span class="ruby-operator">..</span><span class="ruby-value">1</span>] }
1419
- 565: <span class="ruby-identifier">@@expectedTokens</span> <span class="ruby-operator">+=</span> <span class="ruby-identifier">keys</span>
1420
- 566: <span class="ruby-identifier">@@expectedTokens</span>.<span class="ruby-identifier">sort!</span>
1421
- 567: <span class="ruby-keyword kw">end</span>
1422
- 568:
1423
- 569: <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">optional?</span>(<span class="ruby-ivar">@rules</span>) <span class="ruby-operator">||</span> <span class="ruby-identifier">repeatMode</span>
1424
- 570: <span class="ruby-identifier">error</span>(<span class="ruby-value str">'unexpctd_token'</span>,
1425
- 571: (<span class="ruby-identifier">token</span>[<span class="ruby-value">0</span>] <span class="ruby-operator">!=</span> <span class="ruby-keyword kw">false</span> <span class="ruby-operator">?</span>
1426
- 572: <span class="ruby-node">&quot;Unexpected token '#{token[1]}' of type &quot;</span> <span class="ruby-operator">+</span>
1427
- 573: <span class="ruby-node">&quot;'#{token[0]}'. &quot;</span> <span class="ruby-operator">:</span>
1428
- 574: <span class="ruby-node">&quot;Unexpected end of file in #{@scanner.fileName}. &quot;</span>) <span class="ruby-operator">+</span>
1429
- 575: (<span class="ruby-identifier">@@expectedTokens</span>.<span class="ruby-identifier">length</span> <span class="ruby-operator">&gt;</span> <span class="ruby-value">1</span> <span class="ruby-operator">?</span>
1430
- 576: <span class="ruby-node">&quot;Expecting one of #{@@expectedTokens.join(', ')}&quot;</span> <span class="ruby-operator">:</span>
1431
- 577: <span class="ruby-node">&quot;Expecting #{@@expectedTokens[0]}&quot;</span>), <span class="ruby-identifier">token</span>[<span class="ruby-value">2</span>])
1432
- 578: <span class="ruby-keyword kw">end</span>
1433
- 579: <span class="ruby-identifier">returnToken</span>(<span class="ruby-identifier">token</span>)
1434
- 580: <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">nil</span>
1435
- 581: <span class="ruby-keyword kw">end</span>
1436
- 582:
1437
- 583: <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">pattern</span>(<span class="ruby-identifier">patIdx</span>)
1438
- 584: <span class="ruby-keyword kw">end</span></pre>
1383
+ <span class="ruby-comment cmt"># File lib/TextParser.rb, line 400</span>
1384
+ 400: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">dumpStack</span>
1385
+ 401: <span class="ruby-comment cmt">#puts &quot;Stack level #{@stack.length}&quot;</span>
1386
+ 402: <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">sl</span><span class="ruby-operator">|</span>
1387
+ 403: <span class="ruby-identifier">print</span> <span class="ruby-node">&quot;#{@stack.index(sl)}: &quot;</span>
1388
+ 404: <span class="ruby-identifier">sl</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">v</span><span class="ruby-operator">|</span>
1389
+ 405: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">v</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Array</span>)
1390
+ 406: <span class="ruby-keyword kw">begin</span>
1391
+ 407: <span class="ruby-identifier">print</span> <span class="ruby-node">&quot;[#{v.join('|')}]|&quot;</span>
1392
+ 408: <span class="ruby-keyword kw">rescue</span>
1393
+ 409: <span class="ruby-identifier">print</span> <span class="ruby-node">&quot;[#{v[0].class}...]|&quot;</span>
1394
+ 410: <span class="ruby-keyword kw">end</span>
1395
+ 411: <span class="ruby-keyword kw">else</span>
1396
+ 412: <span class="ruby-keyword kw">begin</span>
1397
+ 413: <span class="ruby-identifier">print</span> <span class="ruby-node">&quot;#{v}|&quot;</span>
1398
+ 414: <span class="ruby-keyword kw">rescue</span>
1399
+ 415: <span class="ruby-identifier">print</span> <span class="ruby-identifier">v</span>.<span class="ruby-identifier">class</span>
1400
+ 416: <span class="ruby-keyword kw">end</span>
1401
+ 417: <span class="ruby-keyword kw">end</span>
1402
+ 418: <span class="ruby-keyword kw">end</span>
1403
+ 419: <span class="ruby-identifier">print</span> <span class="ruby-node">&quot; -&gt; #{sl.state ? sl.state.to_s(true) : 'nil'} #{sl.function.nil? ? '' : '(Called)'}&quot;</span>
1404
+ 420: <span class="ruby-identifier">puts</span> <span class="ruby-value str">&quot;&quot;</span>
1405
+ 421: <span class="ruby-keyword kw">end</span>
1406
+ 422: <span class="ruby-keyword kw">end</span></pre>
1439
1407
  </div>
1440
1408
 
1441
1409
  </div>
@@ -1446,13 +1414,13 @@ href="TextParser.html#method-i-parse">TextParser#parse</a>.
1446
1414
  </div>
1447
1415
 
1448
1416
 
1449
- <div id="get-ext-oken-method" class="method-detail ">
1450
- <a name="method-i-getNextToken"></a>
1417
+ <div id="finish-attern-method" class="method-detail ">
1418
+ <a name="method-i-finishPattern"></a>
1451
1419
 
1452
1420
  <div class="method-heading">
1453
1421
 
1454
- <span class="method-name">getNextToken</span><span
1455
- class="method-args">()</span>
1422
+ <span class="method-name">finishPattern</span><span
1423
+ class="method-args">(token)</span>
1456
1424
  <span class="method-click-advice">click to toggle source</span>
1457
1425
 
1458
1426
  </div>
@@ -1464,19 +1432,54 @@ href="TextParser.html#method-i-parse">TextParser#parse</a>.
1464
1432
 
1465
1433
 
1466
1434
  <div class="method-source-code"
1467
- id="get-ext-oken-source">
1435
+ id="finish-attern-source">
1468
1436
  <pre>
1469
- <span class="ruby-comment cmt"># File lib/TextParser.rb, line 526</span>
1470
- 526: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">getNextToken</span>
1471
- 527: <span class="ruby-identifier">token</span> = <span class="ruby-identifier">nextToken</span>
1472
- 528: <span class="ruby-comment cmt">#Log &lt;&lt; &quot;Token: [#{token[0]}][#{token[1]}]&quot;</span>
1473
- 529: <span class="ruby-keyword kw">if</span> <span class="ruby-ivar">@badVariables</span>.<span class="ruby-identifier">include?</span>(<span class="ruby-identifier">token</span>[<span class="ruby-value">0</span>])
1474
- 530: <span class="ruby-identifier">error</span>(<span class="ruby-value str">'unsupported_token'</span>,
1475
- 531: <span class="ruby-node">&quot;The token #{token[1]} is not supported in this context.&quot;</span>,
1476
- 532: <span class="ruby-identifier">token</span>[<span class="ruby-value">2</span>])
1477
- 533: <span class="ruby-keyword kw">end</span>
1478
- 534: <span class="ruby-identifier">token</span>
1479
- 535: <span class="ruby-keyword kw">end</span></pre>
1437
+ <span class="ruby-comment cmt"># File lib/TextParser.rb, line 354</span>
1438
+ 354: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">finishPattern</span>(<span class="ruby-identifier">token</span>)
1439
+ 355: <span class="ruby-comment cmt">#dumpStack</span>
1440
+ 356: <span class="ruby-comment cmt"># To finish a pattern we need to pop the StackElement with the token</span>
1441
+ 357: <span class="ruby-comment cmt"># values from the stack.</span>
1442
+ 358: <span class="ruby-identifier">stackEntry</span> = <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">pop</span>
1443
+ 359: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">stackEntry</span>.<span class="ruby-identifier">nil?</span> <span class="ruby-operator">||</span> <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">empty?</span>
1444
+ 360: <span class="ruby-comment cmt"># Check if we have reached the bottom of the stack.</span>
1445
+ 361: <span class="ruby-identifier">token</span> = <span class="ruby-identifier">getNextToken</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">token</span>
1446
+ 362: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">token</span>[<span class="ruby-value">0</span>] <span class="ruby-operator">==</span> <span class="ruby-value">:endOfText</span>
1447
+ 363: <span class="ruby-comment cmt"># If the token is the end of the top-level file, we're done. We push</span>
1448
+ 364: <span class="ruby-comment cmt"># back the StackEntry since it holds the overall result of the</span>
1449
+ 365: <span class="ruby-comment cmt"># parsing.</span>
1450
+ 366: <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">push</span>(<span class="ruby-identifier">stackEntry</span>)
1451
+ 367: <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">true</span>
1452
+ 368: <span class="ruby-keyword kw">end</span>
1453
+ 369: <span class="ruby-comment cmt"># If it's not the EOF token, we found a token that violates the syntax</span>
1454
+ 370: <span class="ruby-comment cmt"># rules.</span>
1455
+ 371: <span class="ruby-identifier">error</span>(<span class="ruby-value str">'unexpctd_token'</span>, <span class="ruby-node">&quot;Unexpected token '#{token[1]}' found. &quot;</span> <span class="ruby-operator">+</span>
1456
+ 372: <span class="ruby-value str">&quot;Expecting one of &quot;</span> <span class="ruby-operator">+</span>
1457
+ 373: <span class="ruby-node">&quot;#{stackEntry.state.expectedTokens.join(', ')}&quot;</span>)
1458
+ 374: <span class="ruby-keyword kw">end</span>
1459
+ 375: <span class="ruby-comment cmt"># Memorize if the rule for this pattern was repeatable. Then we will</span>
1460
+ 376: <span class="ruby-comment cmt"># store the result of the pattern in an Array.</span>
1461
+ 377: <span class="ruby-identifier">ruleIsRepeatable</span> = <span class="ruby-identifier">stackEntry</span>.<span class="ruby-identifier">state</span>.<span class="ruby-identifier">rule</span>.<span class="ruby-identifier">repeatable</span>
1462
+ 378:
1463
+ 379: <span class="ruby-identifier">state</span> = <span class="ruby-identifier">stackEntry</span>.<span class="ruby-identifier">state</span>
1464
+ 380: <span class="ruby-identifier">result</span> = <span class="ruby-keyword kw">nil</span>
1465
+ 381: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">state</span>.<span class="ruby-identifier">pattern</span>.<span class="ruby-identifier">function</span>
1466
+ 382: <span class="ruby-comment cmt"># Make the token values and their SourceFileInfo available.</span>
1467
+ 383: <span class="ruby-ivar">@val</span> = <span class="ruby-identifier">stackEntry</span>.<span class="ruby-identifier">val</span>
1468
+ 384: <span class="ruby-ivar">@sourceFileInfo</span> = <span class="ruby-identifier">stackEntry</span>.<span class="ruby-identifier">sourceFileInfo</span>
1469
+ 385: <span class="ruby-comment cmt"># Now call the pattern action to compute the value of the pattern.</span>
1470
+ 386: <span class="ruby-identifier">result</span> = <span class="ruby-identifier">state</span>.<span class="ruby-identifier">pattern</span>.<span class="ruby-identifier">function</span>.<span class="ruby-identifier">call</span>
1471
+ 387: <span class="ruby-keyword kw">end</span>
1472
+ 388:
1473
+ 389: <span class="ruby-comment cmt"># We use the SourceFileInfo of the first token of the pattern to store</span>
1474
+ 390: <span class="ruby-comment cmt"># it with the result of the pattern.</span>
1475
+ 391: <span class="ruby-identifier">firstSourceFileInfo</span> = <span class="ruby-identifier">stackEntry</span>.<span class="ruby-identifier">firstSourceFileInfo</span>
1476
+ 392: <span class="ruby-comment cmt"># Store the result at the correct position into the next lower level of</span>
1477
+ 393: <span class="ruby-comment cmt"># the stack.</span>
1478
+ 394: <span class="ruby-identifier">stackEntry</span> = <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">last</span>
1479
+ 395: <span class="ruby-identifier">stackEntry</span>.<span class="ruby-identifier">insert</span>(<span class="ruby-identifier">stackEntry</span>.<span class="ruby-identifier">state</span>.<span class="ruby-identifier">index</span>, <span class="ruby-identifier">result</span>,
1480
+ 396: <span class="ruby-identifier">firstSourceFileInfo</span>, <span class="ruby-identifier">ruleIsRepeatable</span>)
1481
+ 397: <span class="ruby-keyword kw">false</span>
1482
+ 398: <span class="ruby-keyword kw">end</span></pre>
1480
1483
  </div>
1481
1484
 
1482
1485
  </div>
@@ -1487,83 +1490,37 @@ href="TextParser.html#method-i-parse">TextParser#parse</a>.
1487
1490
  </div>
1488
1491
 
1489
1492
 
1490
- <div id="get-ransitions-method" class="method-detail ">
1491
- <a name="method-i-getTransitions"></a>
1493
+ <div id="get-ext-oken-method" class="method-detail ">
1494
+ <a name="method-i-getNextToken"></a>
1492
1495
 
1493
1496
  <div class="method-heading">
1494
1497
 
1495
- <span class="method-name">getTransitions</span><span
1496
- class="method-args">(rule)</span>
1498
+ <span class="method-name">getNextToken</span><span
1499
+ class="method-args">()</span>
1497
1500
  <span class="method-click-advice">click to toggle source</span>
1498
1501
 
1499
1502
  </div>
1500
1503
 
1501
1504
  <div class="method-description">
1502
1505
 
1503
- <p>
1504
- getTransitions recursively determines all possible target tokens that the
1505
- <em>rule</em> matches. A target token can either be a fixed token (prefixed
1506
- with _), a variable token (prefixed with $) or an end token (just a .). The
1507
- list of found target tokens is stored in the <em>transitions</em> list of
1508
- the rule. For each rule pattern we store the transitions for this pattern
1509
- in a token -> rule hash.
1510
- </p>
1506
+
1511
1507
 
1512
1508
 
1513
1509
 
1514
1510
  <div class="method-source-code"
1515
- id="get-ransitions-source">
1511
+ id="get-ext-oken-source">
1516
1512
  <pre>
1517
- <span class="ruby-comment cmt"># File lib/TextParser.rb, line 227</span>
1518
- 227: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">getTransitions</span>(<span class="ruby-identifier">rule</span>)
1519
- 228: <span class="ruby-comment cmt"># If we have processed this rule before we can just return a copy</span>
1520
- 229: <span class="ruby-comment cmt"># of the transitions of this rule. This avoids endless recursions.</span>
1521
- 230: <span class="ruby-keyword kw">return</span> <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">transitions</span>.<span class="ruby-identifier">dup</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">transitions</span>.<span class="ruby-identifier">empty?</span>
1522
- 231:
1523
- 232: <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">transitions</span> = []
1524
- 233: <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">patterns</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">pat</span><span class="ruby-operator">|</span>
1525
- 234: <span class="ruby-identifier">allTokensOptional</span> = <span class="ruby-keyword kw">true</span>
1526
- 235: <span class="ruby-identifier">transitions</span> = { }
1527
- 236: <span class="ruby-identifier">pat</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">token</span><span class="ruby-operator">|</span>
1528
- 237: <span class="ruby-identifier">tokenId</span> = <span class="ruby-identifier">token</span>[<span class="ruby-value">1</span><span class="ruby-operator">..</span><span class="ruby-value">1</span>]
1529
- 238: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">token</span>[<span class="ruby-value">0</span>] <span class="ruby-operator">==</span> <span class="ruby-value">!!</span>
1530
- 239: <span class="ruby-keyword kw">unless</span> <span class="ruby-ivar">@rules</span>.<span class="ruby-identifier">has_key?</span>(<span class="ruby-identifier">tokenId</span>)
1531
- 240: <span class="ruby-identifier">raise</span> <span class="ruby-node">&quot;Fatal Error: Unknown reference to #{tokenId} in pattern &quot;</span> <span class="ruby-operator">+</span>
1532
- 241: <span class="ruby-node">&quot;#{pat} + of rule #{rule.name}&quot;</span>
1533
- 242: <span class="ruby-keyword kw">end</span>
1534
- 243: <span class="ruby-identifier">refRule</span> = <span class="ruby-ivar">@rules</span>[<span class="ruby-identifier">tokenId</span>]
1535
- 244: <span class="ruby-comment cmt"># If the referenced rule describes optional content, we need to look</span>
1536
- 245: <span class="ruby-comment cmt"># at the next token as well.</span>
1537
- 246: <span class="ruby-identifier">res</span> = <span class="ruby-identifier">getTransitions</span>(<span class="ruby-ivar">@rules</span>[<span class="ruby-identifier">tokenId</span>])
1538
- 247: <span class="ruby-identifier">allTokensOptional</span> = <span class="ruby-keyword kw">false</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">refRule</span>.<span class="ruby-identifier">optional?</span>(<span class="ruby-ivar">@rules</span>)
1539
- 248: <span class="ruby-comment cmt"># Combine the hashes for each pattern into a single hash</span>
1540
- 249: <span class="ruby-identifier">res</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">pat_i</span><span class="ruby-operator">|</span>
1541
- 250: <span class="ruby-identifier">pat_i</span>.<span class="ruby-identifier">each</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">tok</span>, <span class="ruby-identifier">r</span><span class="ruby-operator">|</span> <span class="ruby-identifier">transitions</span>[<span class="ruby-identifier">tok</span>] = <span class="ruby-identifier">r</span> }
1542
- 251: <span class="ruby-keyword kw">end</span>
1543
- 252: <span class="ruby-keyword kw">elsif</span> <span class="ruby-value str">'_$.'</span>.<span class="ruby-identifier">include?</span>(<span class="ruby-identifier">token</span>[<span class="ruby-value">0</span>])
1544
- 253: <span class="ruby-identifier">transitions</span>[<span class="ruby-identifier">token</span>] = <span class="ruby-identifier">rule</span>
1545
- 254: <span class="ruby-identifier">allTokensOptional</span> = <span class="ruby-keyword kw">false</span>
1546
- 255: <span class="ruby-keyword kw">else</span>
1547
- 256: <span class="ruby-identifier">raise</span> <span class="ruby-value str">'Fatal Error: Illegal token type specifier used for token'</span> <span class="ruby-operator">+</span>
1548
- 257: <span class="ruby-node">&quot;: #{tokenId}&quot;</span>
1549
- 258: <span class="ruby-keyword kw">end</span>
1550
- 259: <span class="ruby-keyword kw">break</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">allTokensOptional</span>
1551
- 260: <span class="ruby-keyword kw">end</span>
1552
- 261: <span class="ruby-comment cmt"># Make sure that we only have one possible transition for each</span>
1553
- 262: <span class="ruby-comment cmt"># target.</span>
1554
- 263: <span class="ruby-identifier">transitions</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">key</span>, <span class="ruby-identifier">value</span><span class="ruby-operator">|</span>
1555
- 264: <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">transitions</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">trans</span><span class="ruby-operator">|</span>
1556
- 265: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">trans</span>.<span class="ruby-identifier">has_key?</span>(<span class="ruby-identifier">key</span>)
1557
- 266: <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">dump</span>
1558
- 267: <span class="ruby-identifier">raise</span> <span class="ruby-node">&quot;Fatal Error: Rule #{rule.name} has ambiguous &quot;</span> <span class="ruby-operator">+</span>
1559
- 268: <span class="ruby-node">&quot;transitions for target #{key}&quot;</span>
1560
- 269: <span class="ruby-keyword kw">end</span>
1561
- 270: <span class="ruby-keyword kw">end</span>
1562
- 271: <span class="ruby-keyword kw">end</span>
1563
- 272: <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">transitions</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-identifier">transitions</span>
1564
- 273: <span class="ruby-keyword kw">end</span>
1565
- 274: <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">transitions</span>.<span class="ruby-identifier">dup</span>
1566
- 275: <span class="ruby-keyword kw">end</span></pre>
1513
+ <span class="ruby-comment cmt"># File lib/TextParser.rb, line 447</span>
1514
+ 447: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">getNextToken</span>
1515
+ 448: <span class="ruby-identifier">token</span> = <span class="ruby-identifier">nextToken</span>
1516
+ 449: <span class="ruby-comment cmt">#Log &lt;&lt; &quot;Token: [#{token[0]}][#{token[1]}]&quot;</span>
1517
+ 450: <span class="ruby-keyword kw">if</span> <span class="ruby-ivar">@blockedVariables</span>[<span class="ruby-identifier">token</span>[<span class="ruby-value">0</span>]]
1518
+ 451: <span class="ruby-identifier">error</span>(<span class="ruby-value str">'unsupported_token'</span>,
1519
+ 452: <span class="ruby-node">&quot;The token #{token[1]} is not supported in this context.&quot;</span>,
1520
+ 453: <span class="ruby-identifier">token</span>[<span class="ruby-value">2</span>])
1521
+ 454: <span class="ruby-keyword kw">end</span>
1522
+ 455: <span class="ruby-identifier">token</span>
1523
+ 456: <span class="ruby-keyword kw">end</span></pre>
1567
1524
  </div>
1568
1525
 
1569
1526
  </div>
@@ -1574,12 +1531,12 @@ in a token -> rule hash.
1574
1531
  </div>
1575
1532
 
1576
1533
 
1577
- <div id="parse-ule--method" class="method-detail ">
1578
- <a name="method-i-parseRuleNR"></a>
1534
+ <div id="parse--method" class="method-detail ">
1535
+ <a name="method-i-parseFSM"></a>
1579
1536
 
1580
1537
  <div class="method-heading">
1581
1538
 
1582
- <span class="method-name">parseRuleNR</span><span
1539
+ <span class="method-name">parseFSM</span><span
1583
1540
  class="method-args">(rule)</span>
1584
1541
  <span class="method-click-advice">click to toggle source</span>
1585
1542
 
@@ -1587,160 +1544,102 @@ in a token -> rule hash.
1587
1544
 
1588
1545
  <div class="method-description">
1589
1546
 
1590
- <p>
1591
- This function processes the input starting with the syntax description of
1592
- <em>rule</em>. It&#8217;s implemented as an unrolled recursion. It
1593
- recursively iterates over the rule tree as controlled by the input file.
1594
- This version is not limited by the size of the system stack. So far,
1595
- I&#8217;m not aware of any project that is too large for the system stack.
1596
- Since the recursive version parseRuleR is about 8% faster and has cleaner
1597
- code, we use that by default.
1598
- </p>
1547
+
1599
1548
 
1600
1549
 
1601
1550
 
1602
1551
  <div class="method-source-code"
1603
- id="parse-ule--source">
1552
+ id="parse--source">
1604
1553
  <pre>
1605
- <span class="ruby-comment cmt"># File lib/TextParser.rb, line 387</span>
1606
- 387: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">parseRuleNR</span>(<span class="ruby-identifier">rule</span>)
1607
- 388: <span class="ruby-identifier">elementIdx</span> = <span class="ruby-value">0</span>
1608
- 389: <span class="ruby-identifier">recursionResult</span> = <span class="ruby-keyword kw">nil</span>
1609
- 390: <span class="ruby-comment cmt"># These flags are used to managed the control flow to and from the</span>
1610
- 391: <span class="ruby-comment cmt"># recursion point.</span>
1611
- 392: <span class="ruby-identifier">recur</span> = <span class="ruby-identifier">resume</span> = <span class="ruby-keyword kw">false</span>
1612
- 393: <span class="ruby-comment cmt"># The stack that holds the context for the recursion levels. It's either</span>
1613
- 394: <span class="ruby-comment cmt"># just a rule to start a new recursion or an Array of state variables.</span>
1614
- 395: <span class="ruby-identifier">recursionStack</span> = [ <span class="ruby-identifier">rule</span> ]
1615
- 396: <span class="ruby-keyword kw">begin</span>
1616
- 397: <span class="ruby-comment cmt"># Pop the top entry from the recursion stack.</span>
1617
- 398: <span class="ruby-identifier">se</span> = <span class="ruby-identifier">recursionStack</span>.<span class="ruby-identifier">pop</span>
1618
- 399: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">se</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Array</span>)
1619
- 400: <span class="ruby-comment cmt"># We have essentially finished a recursion level and need to get</span>
1620
- 401: <span class="ruby-comment cmt"># back to the place where we started the recursion. First, we need</span>
1621
- 402: <span class="ruby-comment cmt"># to restore the state again.</span>
1622
- 403: <span class="ruby-identifier">rule</span>, <span class="ruby-identifier">pattern</span>, <span class="ruby-identifier">elementIdx</span>, <span class="ruby-identifier">result</span>, <span class="ruby-identifier">repeatMode</span>, <span class="ruby-identifier">sfi</span> = <span class="ruby-identifier">se</span>
1623
- 404: <span class="ruby-comment cmt">#Log &lt;&lt; &quot;Recursion loop started in resume mode for rule #{rule.name}&quot;</span>
1624
- 405: <span class="ruby-comment cmt"># Now jump to the recursion point without doing anything else.</span>
1625
- 406: <span class="ruby-identifier">resume</span> = <span class="ruby-keyword kw">true</span>
1626
- 407: <span class="ruby-keyword kw">else</span>
1627
- 408: <span class="ruby-comment cmt"># Start a new recursion level. The rule tells us how to interpret</span>
1628
- 409: <span class="ruby-comment cmt"># the input text.</span>
1629
- 410: <span class="ruby-identifier">rule</span> = <span class="ruby-identifier">se</span>
1630
- 411: <span class="ruby-comment cmt">#Log.enter('parseRuleNR', &quot;Parsing with rule #{rule.name}&quot;)</span>
1631
- 412: <span class="ruby-identifier">resume</span> = <span class="ruby-keyword kw">false</span>
1632
- 413: <span class="ruby-keyword kw">end</span>
1633
- 414:
1634
- 415: <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">resume</span>
1635
- 416: <span class="ruby-identifier">result</span> = <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">repeatable</span> <span class="ruby-operator">?</span> <span class="ruby-constant">TextParserResultArray</span>.<span class="ruby-identifier">new</span> <span class="ruby-operator">:</span> <span class="ruby-keyword kw">nil</span>
1636
- 417: <span class="ruby-comment cmt"># Rules can be marked 'repeatable'. This flag will be set to true</span>
1637
- 418: <span class="ruby-comment cmt"># after the first iteration has been completed.</span>
1638
- 419: <span class="ruby-identifier">repeatMode</span> = <span class="ruby-keyword kw">false</span>
1639
- 420: <span class="ruby-keyword kw">end</span>
1640
- 421:
1641
- 422: <span class="ruby-identifier">loop</span> <span class="ruby-keyword kw">do</span>
1642
- 423: <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">resume</span>
1643
- 424: <span class="ruby-comment cmt"># At the beginning of a rule we need a token from the input to</span>
1644
- 425: <span class="ruby-comment cmt"># determine which pattern of the rule needs to be processed.</span>
1645
- 426: <span class="ruby-identifier">token</span> = <span class="ruby-identifier">getNextToken</span>
1646
- 427:
1647
- 428: <span class="ruby-keyword kw">break</span> <span class="ruby-keyword kw">unless</span> (<span class="ruby-identifier">pattern</span> = <span class="ruby-identifier">findPattern</span>(<span class="ruby-identifier">rule</span>, <span class="ruby-identifier">token</span>, <span class="ruby-identifier">repeatMode</span>))
1648
- 429: <span class="ruby-comment cmt"># The @stack will store the resulting value of each element in the</span>
1649
- 430: <span class="ruby-comment cmt"># pattern.</span>
1650
- 431: <span class="ruby-ivar">@stack</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-constant">TextParser</span><span class="ruby-operator">::</span><span class="ruby-constant">StackElement</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">pattern</span>.<span class="ruby-identifier">function</span>)
1651
- 432:
1652
- 433: <span class="ruby-comment cmt"># Once we've found the right pattern, we need to process each</span>
1653
- 434: <span class="ruby-comment cmt"># element.</span>
1654
- 435: <span class="ruby-identifier">elementIdx</span> = <span class="ruby-value">0</span>
1655
- 436: <span class="ruby-keyword kw">end</span>
1656
- 437:
1657
- 438: <span class="ruby-identifier">elementCount</span> = <span class="ruby-identifier">pattern</span>.<span class="ruby-identifier">length</span>
1658
- 439: <span class="ruby-keyword kw">while</span> <span class="ruby-identifier">elementIdx</span> <span class="ruby-operator">&lt;</span> <span class="ruby-identifier">elementCount</span>
1659
- 440: <span class="ruby-identifier">element</span> = <span class="ruby-identifier">pattern</span>[<span class="ruby-identifier">elementIdx</span>]
1660
- 441: <span class="ruby-comment cmt"># Separate the type and token text for pattern element.</span>
1661
- 442: <span class="ruby-identifier">elType</span> = <span class="ruby-identifier">element</span>[<span class="ruby-value">0</span>]
1662
- 443: <span class="ruby-identifier">elToken</span> = <span class="ruby-identifier">element</span>[<span class="ruby-value">1</span><span class="ruby-operator">..</span><span class="ruby-value">1</span>]
1663
- 444: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">elType</span> <span class="ruby-operator">==</span> <span class="ruby-value">!!</span>
1664
- 445: <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">resume</span>
1665
- 446: <span class="ruby-comment cmt"># The element is a reference to another rule. Return the token</span>
1666
- 447: <span class="ruby-comment cmt"># if we still have one and continue with the referenced rule.</span>
1667
- 448: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">token</span>
1668
- 449: <span class="ruby-identifier">sfi</span> = <span class="ruby-identifier">token</span>[<span class="ruby-value">2</span>]
1669
- 450: <span class="ruby-identifier">returnToken</span>(<span class="ruby-identifier">token</span>)
1670
- 451: <span class="ruby-identifier">token</span> = <span class="ruby-keyword kw">nil</span>
1671
- 452: <span class="ruby-keyword kw">else</span>
1672
- 453: <span class="ruby-identifier">sfi</span> = <span class="ruby-keyword kw">nil</span>
1673
- 454: <span class="ruby-keyword kw">end</span>
1674
- 455: <span class="ruby-comment cmt"># This is where the recursion would happen. Instead, we push</span>
1675
- 456: <span class="ruby-comment cmt"># the state variables and then the next rule onto the</span>
1676
- 457: <span class="ruby-comment cmt"># recursion stack.</span>
1677
- 458: <span class="ruby-identifier">recursionStack</span>.<span class="ruby-identifier">push</span>([ <span class="ruby-identifier">rule</span>, <span class="ruby-identifier">pattern</span>, <span class="ruby-identifier">elementIdx</span>, <span class="ruby-identifier">result</span>,
1678
- 459: <span class="ruby-identifier">repeatMode</span>, <span class="ruby-identifier">sfi</span> ])
1679
- 460: <span class="ruby-identifier">recursionStack</span>.<span class="ruby-identifier">push</span>(<span class="ruby-ivar">@rules</span>[<span class="ruby-identifier">elToken</span>])
1680
- 461: <span class="ruby-comment cmt"># Now terminate all but the outer loops without doing anything</span>
1681
- 462: <span class="ruby-comment cmt"># else.</span>
1682
- 463: <span class="ruby-identifier">recur</span> = <span class="ruby-keyword kw">true</span>
1683
- 464: <span class="ruby-keyword kw">break</span>
1684
- 465: <span class="ruby-keyword kw">else</span>
1685
- 466: <span class="ruby-comment cmt"># We're back right after where the recursion started. Store</span>
1686
- 467: <span class="ruby-comment cmt"># the result and turn resume mode off again.</span>
1687
- 468: <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">last</span>.<span class="ruby-identifier">store</span>(<span class="ruby-identifier">recursionResult</span>, <span class="ruby-identifier">sfi</span>)
1688
- 469: <span class="ruby-identifier">resume</span> = <span class="ruby-keyword kw">false</span>
1689
- 470: <span class="ruby-keyword kw">end</span>
1690
- 471: <span class="ruby-keyword kw">else</span>
1691
- 472: <span class="ruby-comment cmt"># In case the element is a keyword or variable we have to get a</span>
1692
- 473: <span class="ruby-comment cmt"># new token if we don't have one anymore.</span>
1693
- 474: <span class="ruby-identifier">token</span> = <span class="ruby-identifier">getNextToken</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">token</span>
1694
- 475:
1695
- 476: <span class="ruby-identifier">processNormalElements</span>(<span class="ruby-identifier">elType</span>, <span class="ruby-identifier">elToken</span>, <span class="ruby-identifier">token</span>)
1696
- 477:
1697
- 478: <span class="ruby-comment cmt"># The token has been consumed. Reset the variable.</span>
1698
- 479: <span class="ruby-identifier">token</span> = <span class="ruby-keyword kw">nil</span>
1699
- 480: <span class="ruby-identifier">@@expectedTokens</span> = []
1700
- 481: <span class="ruby-keyword kw">end</span>
1701
- 482: <span class="ruby-identifier">elementIdx</span> <span class="ruby-operator">+=</span> <span class="ruby-value">1</span>
1702
- 483: <span class="ruby-keyword kw">end</span> <span class="ruby-comment cmt"># of pattern while loop</span>
1703
- 484:
1704
- 485: <span class="ruby-comment cmt"># Skip the rest of the loop in recur mode.</span>
1705
- 486: <span class="ruby-keyword kw">break</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">recur</span>
1706
- 487:
1707
- 488: <span class="ruby-identifier">elementIdx</span> = <span class="ruby-value">0</span>
1708
- 489:
1709
- 490: <span class="ruby-comment cmt"># Once the complete pattern has been processed we call the</span>
1710
- 491: <span class="ruby-comment cmt"># processing function for this pattern to operate on the value</span>
1711
- 492: <span class="ruby-comment cmt"># array. Then pop the entry for this rule from the stack. The</span>
1712
- 493: <span class="ruby-comment cmt"># called function will use @val and @sourceFileInfo to retrieve</span>
1713
- 494: <span class="ruby-comment cmt"># data from the parser.</span>
1714
- 495: <span class="ruby-ivar">@val</span> = <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">last</span>.<span class="ruby-identifier">val</span>
1715
- 496: <span class="ruby-ivar">@sourceFileInfo</span> = <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">last</span>.<span class="ruby-identifier">sourceFileInfo</span>
1716
- 497: <span class="ruby-identifier">res</span> = <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">last</span>.<span class="ruby-identifier">function</span> <span class="ruby-operator">?</span> <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">last</span>.<span class="ruby-identifier">function</span>.<span class="ruby-identifier">call</span> <span class="ruby-operator">:</span> <span class="ruby-keyword kw">nil</span>
1717
- 498: <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">pop</span>
1718
- 499:
1719
- 500: <span class="ruby-comment cmt"># If the rule is not repeatable we can store the result and break</span>
1720
- 501: <span class="ruby-comment cmt"># the outer loop to exit the function.</span>
1721
- 502: <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">repeatable</span>
1722
- 503: <span class="ruby-identifier">result</span> = <span class="ruby-identifier">res</span>
1723
- 504: <span class="ruby-keyword kw">break</span>
1724
- 505: <span class="ruby-keyword kw">end</span>
1725
- 506:
1726
- 507: <span class="ruby-comment cmt"># Otherwise we append the result to the result array and turn repeat</span>
1727
- 508: <span class="ruby-comment cmt"># mode on.</span>
1728
- 509: <span class="ruby-identifier">result</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-identifier">res</span>
1729
- 510: <span class="ruby-comment cmt"># We have completed the first iteration. Set the repeat mode flag to</span>
1730
- 511: <span class="ruby-comment cmt"># indicate that further iterations are already re-runs.</span>
1731
- 512: <span class="ruby-identifier">repeatMode</span> = <span class="ruby-keyword kw">true</span>
1732
- 513: <span class="ruby-keyword kw">end</span> <span class="ruby-comment cmt"># of rule processing loop</span>
1733
- 514:
1734
- 515: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">recur</span>
1735
- 516: <span class="ruby-identifier">recur</span> = <span class="ruby-keyword kw">false</span>
1736
- 517: <span class="ruby-keyword kw">else</span>
1737
- 518: <span class="ruby-comment cmt">#Log.exit('parseRuleNR', &quot;Finished rule #{rule.name}&quot;)</span>
1738
- 519: <span class="ruby-identifier">recursionResult</span> = <span class="ruby-identifier">result</span>
1739
- 520: <span class="ruby-keyword kw">end</span>
1740
- 521: <span class="ruby-keyword kw">end</span> <span class="ruby-keyword kw">while</span> <span class="ruby-operator">!</span><span class="ruby-identifier">recursionStack</span>.<span class="ruby-identifier">empty?</span>
1741
- 522:
1742
- 523: <span class="ruby-keyword kw">return</span> <span class="ruby-identifier">result</span>
1743
- 524: <span class="ruby-keyword kw">end</span></pre>
1554
+ <span class="ruby-comment cmt"># File lib/TextParser.rb, line 265</span>
1555
+ 265: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">parseFSM</span>(<span class="ruby-identifier">rule</span>)
1556
+ 266: <span class="ruby-keyword kw">unless</span> (<span class="ruby-identifier">state</span> = <span class="ruby-ivar">@states</span>[[ <span class="ruby-identifier">rule</span>, <span class="ruby-keyword kw">nil</span>, <span class="ruby-value">0</span> ]])
1557
+ 267: <span class="ruby-identifier">error</span>(<span class="ruby-value str">&quot;no_start_state&quot;</span>, <span class="ruby-node">&quot;No start state for rule #{rule.name} found&quot;</span>)
1558
+ 268: <span class="ruby-keyword kw">end</span>
1559
+ 269: <span class="ruby-ivar">@stack</span> = [ <span class="ruby-constant">TextParser</span><span class="ruby-operator">::</span><span class="ruby-constant">StackElement</span>.<span class="ruby-identifier">new</span>(<span class="ruby-keyword kw">nil</span>, <span class="ruby-identifier">state</span>) ]
1560
+ 270:
1561
+ 271: <span class="ruby-identifier">loop</span> <span class="ruby-keyword kw">do</span>
1562
+ 272: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">state</span>.<span class="ruby-identifier">transitions</span>.<span class="ruby-identifier">empty?</span>
1563
+ 273: <span class="ruby-comment cmt"># The final states of each pattern have no pre-compiled transitions.</span>
1564
+ 274: <span class="ruby-comment cmt"># For such a state, we don't need to get a new token.</span>
1565
+ 275: <span class="ruby-identifier">transition</span> = <span class="ruby-identifier">token</span> = <span class="ruby-keyword kw">nil</span>
1566
+ 276: <span class="ruby-keyword kw">else</span>
1567
+ 277: <span class="ruby-identifier">transition</span> = <span class="ruby-identifier">state</span>.<span class="ruby-identifier">transition</span>(<span class="ruby-identifier">token</span> = <span class="ruby-identifier">getNextToken</span>)
1568
+ 278: <span class="ruby-keyword kw">end</span>
1569
+ 279:
1570
+ 280: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">transition</span>
1571
+ 281: <span class="ruby-comment cmt"># Shift: This for normal state transitions. This may be from one</span>
1572
+ 282: <span class="ruby-comment cmt"># token of a pattern to the next token of the same pattern, to the</span>
1573
+ 283: <span class="ruby-comment cmt"># start of a new pattern or a loop-back to the start of a pattern of</span>
1574
+ 284: <span class="ruby-comment cmt"># the same rule. The transition tells us what state we have to</span>
1575
+ 285: <span class="ruby-comment cmt"># process next.</span>
1576
+ 286: <span class="ruby-identifier">state</span> = <span class="ruby-identifier">transition</span>.<span class="ruby-identifier">state</span>
1577
+ 287:
1578
+ 288: <span class="ruby-comment cmt"># If we have looped-back we need to finish the pattern first. Final</span>
1579
+ 289: <span class="ruby-comment cmt"># tokens of repeatable rules do have transitions!</span>
1580
+ 290: <span class="ruby-identifier">finishPattern</span>(<span class="ruby-identifier">token</span>) <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">transition</span>.<span class="ruby-identifier">loopBack</span>
1581
+ 291:
1582
+ 292: <span class="ruby-comment cmt"># Transitions that enter rules generate states which we need to</span>
1583
+ 293: <span class="ruby-comment cmt"># resume at when a rule has been completely processed. We push this</span>
1584
+ 294: <span class="ruby-comment cmt"># list of states on the @stack.</span>
1585
+ 295: <span class="ruby-identifier">stackElement</span> = <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">last</span>
1586
+ 296: <span class="ruby-identifier">first</span> = <span class="ruby-keyword kw">true</span>
1587
+ 297: <span class="ruby-identifier">transition</span>.<span class="ruby-identifier">stateStack</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">s</span><span class="ruby-operator">|</span>
1588
+ 298: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">first</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">s</span>.<span class="ruby-identifier">pattern</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">stackElement</span>.<span class="ruby-identifier">state</span>.<span class="ruby-identifier">pattern</span>
1589
+ 299: <span class="ruby-comment cmt"># The first state in the list may just be another state of the</span>
1590
+ 300: <span class="ruby-comment cmt"># current pattern. In this case, we already have the</span>
1591
+ 301: <span class="ruby-comment cmt"># StackElement on the @stack. We only need to update the State</span>
1592
+ 302: <span class="ruby-comment cmt"># for the current StackElement.</span>
1593
+ 303: <span class="ruby-identifier">stackElement</span>.<span class="ruby-identifier">state</span> = <span class="ruby-identifier">s</span>
1594
+ 304: <span class="ruby-keyword kw">else</span>
1595
+ 305: <span class="ruby-comment cmt"># For other patterns, we just push a new StackElement onto the</span>
1596
+ 306: <span class="ruby-comment cmt"># @stack.</span>
1597
+ 307: <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">push</span>(<span class="ruby-constant">TextParser</span><span class="ruby-operator">::</span><span class="ruby-constant">StackElement</span>.<span class="ruby-identifier">new</span>(<span class="ruby-keyword kw">nil</span>, <span class="ruby-identifier">s</span>))
1598
+ 308: <span class="ruby-keyword kw">end</span>
1599
+ 309: <span class="ruby-identifier">first</span> = <span class="ruby-keyword kw">false</span>
1600
+ 310: <span class="ruby-keyword kw">end</span>
1601
+ 311:
1602
+ 312: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">state</span>.<span class="ruby-identifier">index</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span>
1603
+ 313: <span class="ruby-comment cmt"># If we have just started with a new pattern (or loop-ed back) we</span>
1604
+ 314: <span class="ruby-comment cmt"># need to push a new StackEntry onto the @stack. The StackEntry</span>
1605
+ 315: <span class="ruby-comment cmt"># stores the result of the pattern and keeps the State that we</span>
1606
+ 316: <span class="ruby-comment cmt"># need to return to in case we jump to other patterns from this</span>
1607
+ 317: <span class="ruby-comment cmt"># pattern.</span>
1608
+ 318: <span class="ruby-identifier">function</span> = <span class="ruby-identifier">state</span>.<span class="ruby-identifier">index</span> <span class="ruby-operator">==</span> <span class="ruby-identifier">state</span>.<span class="ruby-identifier">pattern</span>.<span class="ruby-identifier">tokens</span>.<span class="ruby-identifier">length</span> <span class="ruby-operator">-</span> <span class="ruby-value">1</span> <span class="ruby-operator">?</span>
1609
+ 319: <span class="ruby-identifier">state</span>.<span class="ruby-identifier">pattern</span>.<span class="ruby-identifier">function</span> <span class="ruby-operator">:</span> <span class="ruby-keyword kw">nil</span>
1610
+ 320: <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">push</span>(<span class="ruby-constant">TextParser</span><span class="ruby-operator">::</span><span class="ruby-constant">StackElement</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">state</span>.<span class="ruby-identifier">pattern</span>.<span class="ruby-identifier">function</span>,
1611
+ 321: <span class="ruby-identifier">state</span>))
1612
+ 322: <span class="ruby-keyword kw">end</span>
1613
+ 323:
1614
+ 324: <span class="ruby-comment cmt"># Store the token value in the result Array.</span>
1615
+ 325: <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">last</span>.<span class="ruby-identifier">insert</span>(<span class="ruby-identifier">state</span>.<span class="ruby-identifier">index</span>, <span class="ruby-identifier">token</span>[<span class="ruby-value">1</span>], <span class="ruby-identifier">token</span>[<span class="ruby-value">2</span>], <span class="ruby-keyword kw">false</span>)
1616
+ 326: <span class="ruby-keyword kw">else</span>
1617
+ 327: <span class="ruby-comment cmt"># Reduce: We've reached the end of a rule. There is no pre-compiled</span>
1618
+ 328: <span class="ruby-comment cmt"># transition available. The current token, if we have one, is of no</span>
1619
+ 329: <span class="ruby-comment cmt"># use to us during this state. We just return it to the scanner. The</span>
1620
+ 330: <span class="ruby-comment cmt"># next state is determined by the first matching state from the</span>
1621
+ 331: <span class="ruby-comment cmt"># @stack.</span>
1622
+ 332: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">state</span>.<span class="ruby-identifier">noReduce</span>
1623
+ 333: <span class="ruby-comment cmt"># Only states that finish a rule may trigger a reduce operation.</span>
1624
+ 334: <span class="ruby-comment cmt"># Other states have the noReduce flag set. If a reduce for such a</span>
1625
+ 335: <span class="ruby-comment cmt"># state is triggered, we found a token that is not supported by</span>
1626
+ 336: <span class="ruby-comment cmt"># the syntax rules.</span>
1627
+ 337: <span class="ruby-identifier">error</span>(<span class="ruby-value str">&quot;no_reduce&quot;</span>,
1628
+ 338: <span class="ruby-node">&quot;Unexpected token '#{token[1]}' found. &quot;</span> <span class="ruby-operator">+</span>
1629
+ 339: <span class="ruby-value str">&quot;Expecting one of &quot;</span> <span class="ruby-operator">+</span>
1630
+ 340: <span class="ruby-node">&quot;#{@stack.last.state.expectedTokens.join(', ')}&quot;</span>)
1631
+ 341: <span class="ruby-keyword kw">end</span>
1632
+ 342: <span class="ruby-identifier">returnToken</span>(<span class="ruby-identifier">token</span>) <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">token</span>
1633
+ 343: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">finishPattern</span>(<span class="ruby-identifier">token</span>)
1634
+ 344: <span class="ruby-comment cmt"># Accept: We're done with parsing.</span>
1635
+ 345: <span class="ruby-keyword kw">break</span>
1636
+ 346: <span class="ruby-keyword kw">end</span>
1637
+ 347: <span class="ruby-identifier">state</span> = <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">last</span>.<span class="ruby-identifier">state</span>
1638
+ 348: <span class="ruby-keyword kw">end</span>
1639
+ 349: <span class="ruby-keyword kw">end</span>
1640
+ 350:
1641
+ 351: <span class="ruby-ivar">@stack</span>[<span class="ruby-value">0</span>].<span class="ruby-identifier">val</span>[<span class="ruby-value">0</span>]
1642
+ 352: <span class="ruby-keyword kw">end</span></pre>
1744
1643
  </div>
1745
1644
 
1746
1645
  </div>
@@ -1751,13 +1650,13 @@ code, we use that by default.
1751
1650
  </div>
1752
1651
 
1753
1652
 
1754
- <div id="parse-ule--method" class="method-detail ">
1755
- <a name="method-i-parseRuleR"></a>
1653
+ <div id="restore-sm-tack-method" class="method-detail ">
1654
+ <a name="method-i-restoreFsmStack"></a>
1756
1655
 
1757
1656
  <div class="method-heading">
1758
1657
 
1759
- <span class="method-name">parseRuleR</span><span
1760
- class="method-args">(rule)</span>
1658
+ <span class="method-name">restoreFsmStack</span><span
1659
+ class="method-args">()</span>
1761
1660
  <span class="method-click-advice">click to toggle source</span>
1762
1661
 
1763
1662
  </div>
@@ -1765,91 +1664,25 @@ code, we use that by default.
1765
1664
  <div class="method-description">
1766
1665
 
1767
1666
  <p>
1768
- This function processes the input starting with the syntax description of
1769
- <em>rule</em>. It recursively calls this function whenever the syntax
1770
- description contains the reference to another rule. This recursive version
1771
- has cleaner code and is about 8% faster than parseRuleNR.
1667
+ Convert the FSM stack state entries from [ rule, pattern, index ] into the
1668
+ respective <a href="TextParser/State.html">State</a> objects again.
1772
1669
  </p>
1773
1670
 
1774
1671
 
1775
1672
 
1776
1673
  <div class="method-source-code"
1777
- id="parse-ule--source">
1674
+ id="restore-sm-tack-source">
1778
1675
  <pre>
1779
- <span class="ruby-comment cmt"># File lib/TextParser.rb, line 306</span>
1780
- 306: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">parseRuleR</span>(<span class="ruby-identifier">rule</span>)
1781
- 307: <span class="ruby-comment cmt">#Log.enter('parseRuleR', &quot;Parsing with rule #{rule.name}&quot;)</span>
1782
- 308: <span class="ruby-comment cmt">#puts &quot;Parsing with rule #{rule.name}&quot;</span>
1783
- 309: <span class="ruby-identifier">result</span> = <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">repeatable</span> <span class="ruby-operator">?</span> <span class="ruby-constant">TextParserResultArray</span>.<span class="ruby-identifier">new</span> <span class="ruby-operator">:</span> <span class="ruby-keyword kw">nil</span>
1784
- 310: <span class="ruby-comment cmt"># Rules can be marked 'repeatable'. This flag will be set to true after</span>
1785
- 311: <span class="ruby-comment cmt"># the first iteration has been completed.</span>
1786
- 312: <span class="ruby-identifier">repeatMode</span> = <span class="ruby-keyword kw">false</span>
1787
- 313: <span class="ruby-identifier">loop</span> <span class="ruby-keyword kw">do</span>
1788
- 314: <span class="ruby-comment cmt"># At the beginning of a rule we need a token from the input to determine</span>
1789
- 315: <span class="ruby-comment cmt"># which pattern of the rule needs to be processed.</span>
1790
- 316: <span class="ruby-identifier">token</span> = <span class="ruby-identifier">getNextToken</span>
1791
- 317:
1792
- 318: <span class="ruby-keyword kw">return</span> <span class="ruby-identifier">result</span> <span class="ruby-keyword kw">unless</span> (<span class="ruby-identifier">pattern</span> = <span class="ruby-identifier">findPattern</span>(<span class="ruby-identifier">rule</span>, <span class="ruby-identifier">token</span>, <span class="ruby-identifier">repeatMode</span>))
1793
- 319: <span class="ruby-comment cmt"># The @stack will store the resulting value of each element in the</span>
1794
- 320: <span class="ruby-comment cmt"># pattern.</span>
1795
- 321: <span class="ruby-ivar">@stack</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-constant">TextParser</span><span class="ruby-operator">::</span><span class="ruby-constant">StackElement</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">pattern</span>.<span class="ruby-identifier">function</span>)
1796
- 322:
1797
- 323: <span class="ruby-identifier">pattern</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">element</span><span class="ruby-operator">|</span>
1798
- 324: <span class="ruby-comment cmt"># Separate the type and token text for pattern element.</span>
1799
- 325: <span class="ruby-identifier">elType</span> = <span class="ruby-identifier">element</span>[<span class="ruby-value">0</span>]
1800
- 326: <span class="ruby-identifier">elToken</span> = <span class="ruby-identifier">element</span>[<span class="ruby-value">1</span><span class="ruby-operator">..</span><span class="ruby-value">1</span>]
1801
- 327: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">elType</span> <span class="ruby-operator">==</span> <span class="ruby-value">!!</span>
1802
- 328: <span class="ruby-comment cmt"># The element is a reference to another rule. Return the token if</span>
1803
- 329: <span class="ruby-comment cmt"># we still have one and continue with the referenced rule.</span>
1804
- 330: <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">token</span>.<span class="ruby-identifier">nil?</span>
1805
- 331: <span class="ruby-identifier">sfi</span> = <span class="ruby-identifier">token</span>[<span class="ruby-value">2</span>]
1806
- 332: <span class="ruby-identifier">returnToken</span>(<span class="ruby-identifier">token</span>)
1807
- 333: <span class="ruby-identifier">token</span> = <span class="ruby-keyword kw">nil</span>
1808
- 334: <span class="ruby-keyword kw">else</span>
1809
- 335: <span class="ruby-identifier">sfi</span> = <span class="ruby-keyword kw">nil</span>
1810
- 336: <span class="ruby-keyword kw">end</span>
1811
- 337: <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">last</span>.<span class="ruby-identifier">store</span>(<span class="ruby-identifier">parseRuleR</span>(<span class="ruby-ivar">@rules</span>[<span class="ruby-identifier">elToken</span>]), <span class="ruby-identifier">sfi</span>)
1812
- 338: <span class="ruby-comment cmt">#Log &lt;&lt; &quot;Resuming rule #{rule.name}&quot;</span>
1813
- 339: <span class="ruby-comment cmt">#puts &quot;Resuming rule #{rule.name}&quot;</span>
1814
- 340: <span class="ruby-keyword kw">else</span>
1815
- 341: <span class="ruby-comment cmt"># In case the element is a keyword or variable we have to get a new</span>
1816
- 342: <span class="ruby-comment cmt"># token if we don't have one anymore.</span>
1817
- 343: <span class="ruby-identifier">token</span> = <span class="ruby-identifier">getNextToken</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">token</span>
1818
- 344:
1819
- 345: <span class="ruby-identifier">processNormalElements</span>(<span class="ruby-identifier">elType</span>, <span class="ruby-identifier">elToken</span>, <span class="ruby-identifier">token</span>)
1820
- 346:
1821
- 347: <span class="ruby-comment cmt"># The token has been consumed. Reset the variable.</span>
1822
- 348: <span class="ruby-identifier">token</span> = <span class="ruby-keyword kw">nil</span>
1823
- 349: <span class="ruby-identifier">@@expectedTokens</span> = []
1824
- 350: <span class="ruby-keyword kw">end</span>
1825
- 351: <span class="ruby-keyword kw">end</span>
1826
- 352:
1827
- 353: <span class="ruby-comment cmt"># Once the complete pattern has been processed we call the processing</span>
1828
- 354: <span class="ruby-comment cmt"># function for this pattern to operate on the value array. Then pop the</span>
1829
- 355: <span class="ruby-comment cmt"># entry for this rule from the stack.</span>
1830
- 356: <span class="ruby-ivar">@val</span> = <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">last</span>.<span class="ruby-identifier">val</span>
1831
- 357: <span class="ruby-ivar">@sourceFileInfo</span> = <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">last</span>.<span class="ruby-identifier">sourceFileInfo</span>
1832
- 358: <span class="ruby-identifier">res</span> = <span class="ruby-keyword kw">nil</span>
1833
- 359: <span class="ruby-identifier">res</span> = <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">last</span>.<span class="ruby-identifier">function</span>.<span class="ruby-identifier">call</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">last</span>.<span class="ruby-identifier">function</span>.<span class="ruby-identifier">nil?</span>
1834
- 360: <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">pop</span>
1835
- 361:
1836
- 362: <span class="ruby-comment cmt"># If the rule is not repeatable we can store the result and break the</span>
1837
- 363: <span class="ruby-comment cmt"># outer loop to exit the function.</span>
1838
- 364: <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">rule</span>.<span class="ruby-identifier">repeatable</span>
1839
- 365: <span class="ruby-identifier">result</span> = <span class="ruby-identifier">res</span>
1840
- 366: <span class="ruby-keyword kw">break</span>
1841
- 367: <span class="ruby-keyword kw">end</span>
1842
- 368:
1843
- 369: <span class="ruby-comment cmt"># Otherwise we append the result to the result array and turn repeat</span>
1844
- 370: <span class="ruby-comment cmt"># mode on.</span>
1845
- 371: <span class="ruby-identifier">result</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-identifier">res</span>
1846
- 372: <span class="ruby-identifier">repeatMode</span> = <span class="ruby-keyword kw">true</span>
1847
- 373: <span class="ruby-keyword kw">end</span>
1848
- 374:
1849
- 375: <span class="ruby-comment cmt">#Log.exit('parseRuleR', &quot;Finished rule #{rule.name}&quot;)</span>
1850
- 376: <span class="ruby-comment cmt">#puts &quot;Finished rule #{rule.name}&quot;</span>
1851
- 377: <span class="ruby-keyword kw">return</span> <span class="ruby-identifier">result</span>
1852
- 378: <span class="ruby-keyword kw">end</span></pre>
1676
+ <span class="ruby-comment cmt"># File lib/TextParser.rb, line 437</span>
1677
+ 437: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">restoreFsmStack</span>
1678
+ 438: <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-ivar">@stack</span>
1679
+ 439:
1680
+ 440: <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">s</span><span class="ruby-operator">|</span>
1681
+ 441: <span class="ruby-keyword kw">next</span> <span class="ruby-keyword kw">unless</span> (<span class="ruby-identifier">state</span> = <span class="ruby-ivar">@states</span>[<span class="ruby-identifier">s</span>.<span class="ruby-identifier">state</span>])
1682
+ 442: <span class="ruby-identifier">raise</span> <span class="ruby-value str">&quot;Stack restore failed. Cannot find state&quot;</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">state</span>
1683
+ 443: <span class="ruby-identifier">s</span>.<span class="ruby-identifier">state</span> = <span class="ruby-identifier">state</span>
1684
+ 444: <span class="ruby-keyword kw">end</span>
1685
+ 445: <span class="ruby-keyword kw">end</span></pre>
1853
1686
  </div>
1854
1687
 
1855
1688
  </div>
@@ -1860,13 +1693,13 @@ has cleaner code and is about 8% faster than parseRuleNR.
1860
1693
  </div>
1861
1694
 
1862
1695
 
1863
- <div id="process-ormal-lements-method" class="method-detail ">
1864
- <a name="method-i-processNormalElements"></a>
1696
+ <div id="save-sm-tack-method" class="method-detail ">
1697
+ <a name="method-i-saveFsmStack"></a>
1865
1698
 
1866
1699
  <div class="method-heading">
1867
1700
 
1868
- <span class="method-name">processNormalElements</span><span
1869
- class="method-args">(elType, elToken, token)</span>
1701
+ <span class="method-name">saveFsmStack</span><span
1702
+ class="method-args">()</span>
1870
1703
  <span class="method-click-advice">click to toggle source</span>
1871
1704
 
1872
1705
  </div>
@@ -1874,49 +1707,25 @@ has cleaner code and is about 8% faster than parseRuleNR.
1874
1707
  <div class="method-description">
1875
1708
 
1876
1709
  <p>
1877
- Handle the elements that don&#8217;t trigger a recursion.
1710
+ Convert the FSM stack state entries from <a
1711
+ href="TextParser/State.html">State</a> objects into [ rule, pattern, index
1712
+ ] equivalents.
1878
1713
  </p>
1879
1714
 
1880
1715
 
1881
1716
 
1882
1717
  <div class="method-source-code"
1883
- id="process-ormal-lements-source">
1718
+ id="save-sm-tack-source">
1884
1719
  <pre>
1885
- <span class="ruby-comment cmt"># File lib/TextParser.rb, line 587</span>
1886
- 587: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">processNormalElements</span>(<span class="ruby-identifier">elType</span>, <span class="ruby-identifier">elToken</span>, <span class="ruby-identifier">token</span>)
1887
- 588: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">elType</span> <span class="ruby-operator">==</span> <span class="ruby-value">__</span>
1888
- 589: <span class="ruby-comment cmt"># If the element requires a keyword the token must match this</span>
1889
- 590: <span class="ruby-comment cmt"># keyword.</span>
1890
- 591: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">elToken</span> <span class="ruby-operator">!=</span> <span class="ruby-identifier">token</span>[<span class="ruby-value">1</span>]
1891
- 592: <span class="ruby-identifier">text</span> = <span class="ruby-node">&quot;'#{elToken}' expected but found &quot;</span> <span class="ruby-operator">+</span>
1892
- 593: <span class="ruby-node">&quot;'#{token[1]}' (#{token[0]}).&quot;</span>
1893
- 594: <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">@@expectedTokens</span>.<span class="ruby-identifier">empty?</span>
1894
- 595: <span class="ruby-identifier">text</span> = <span class="ruby-node">&quot;#{@@expectedTokens.join(', ')} or &quot;</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">text</span>
1895
- 596: <span class="ruby-keyword kw">end</span>
1896
- 597: <span class="ruby-identifier">error</span>(<span class="ruby-value str">'spec_keywork_expctd'</span>, <span class="ruby-identifier">text</span>, <span class="ruby-identifier">token</span>[<span class="ruby-value">2</span>])
1897
- 598: <span class="ruby-keyword kw">end</span>
1898
- 599: <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">last</span>.<span class="ruby-identifier">store</span>(<span class="ruby-identifier">elToken</span>, <span class="ruby-identifier">token</span>[<span class="ruby-value">2</span>])
1899
- 600: <span class="ruby-keyword kw">elsif</span> <span class="ruby-identifier">elType</span> <span class="ruby-operator">==</span> <span class="ruby-value">..</span>
1900
- 601: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">token</span>[<span class="ruby-value">0</span><span class="ruby-operator">..</span><span class="ruby-value">1</span>] <span class="ruby-operator">!=</span> [ <span class="ruby-value str">'.'</span>, <span class="ruby-value str">'&lt;END&gt;'</span> ]
1901
- 602: <span class="ruby-identifier">error</span>(<span class="ruby-value str">'end_expected'</span>,
1902
- 603: <span class="ruby-node">&quot;Found garbage at expected end of text: #{token[1]}\n&quot;</span> <span class="ruby-operator">+</span>
1903
- 604: <span class="ruby-value str">&quot;If you see this in the middle of your text, you probably &quot;</span> <span class="ruby-operator">+</span>
1904
- 605: <span class="ruby-value str">&quot;have closed your context too early.&quot;</span>, <span class="ruby-identifier">token</span>[<span class="ruby-value">2</span>])
1905
- 606: <span class="ruby-keyword kw">end</span>
1906
- 607: <span class="ruby-keyword kw">else</span>
1907
- 608: <span class="ruby-comment cmt"># The token must match the expected variable type.</span>
1908
- 609: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">token</span>[<span class="ruby-value">0</span>] <span class="ruby-operator">!=</span> <span class="ruby-identifier">elToken</span>
1909
- 610: <span class="ruby-identifier">text</span> = <span class="ruby-node">&quot;'#{elToken}' expected but found &quot;</span> <span class="ruby-operator">+</span>
1910
- 611: <span class="ruby-node">&quot;'#{token[1]}' (#{token[0]}).&quot;</span>
1911
- 612: <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">@@expectedTokens</span>.<span class="ruby-identifier">empty?</span>
1912
- 613: <span class="ruby-identifier">text</span> = <span class="ruby-node">&quot;#{@@expectedTokens.join(', ')} or &quot;</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">text</span>
1913
- 614: <span class="ruby-keyword kw">end</span>
1914
- 615: <span class="ruby-identifier">error</span>(<span class="ruby-value str">'spec_token_expctd'</span>, <span class="ruby-identifier">text</span>, <span class="ruby-identifier">token</span>[<span class="ruby-value">2</span>])
1915
- 616: <span class="ruby-keyword kw">end</span>
1916
- 617: <span class="ruby-comment cmt"># If the element is a variable store the value of the token.</span>
1917
- 618: <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">last</span>.<span class="ruby-identifier">store</span>(<span class="ruby-identifier">token</span>[<span class="ruby-value">1</span>], <span class="ruby-identifier">token</span>[<span class="ruby-value">2</span>])
1918
- 619: <span class="ruby-keyword kw">end</span>
1919
- 620: <span class="ruby-keyword kw">end</span></pre>
1720
+ <span class="ruby-comment cmt"># File lib/TextParser.rb, line 426</span>
1721
+ 426: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">saveFsmStack</span>
1722
+ 427: <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-ivar">@stack</span>
1723
+ 428:
1724
+ 429: <span class="ruby-ivar">@stack</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">s</span><span class="ruby-operator">|</span>
1725
+ 430: <span class="ruby-keyword kw">next</span> <span class="ruby-keyword kw">unless</span> (<span class="ruby-identifier">st</span> = <span class="ruby-identifier">s</span>.<span class="ruby-identifier">state</span>)
1726
+ 431: <span class="ruby-identifier">s</span>.<span class="ruby-identifier">state</span> = [ <span class="ruby-identifier">st</span>.<span class="ruby-identifier">rule</span>, <span class="ruby-identifier">st</span>.<span class="ruby-identifier">pattern</span>, <span class="ruby-identifier">st</span>.<span class="ruby-identifier">index</span> ]
1727
+ 432: <span class="ruby-keyword kw">end</span>
1728
+ 433: <span class="ruby-keyword kw">end</span></pre>
1920
1729
  </div>
1921
1730
 
1922
1731
  </div>