taskjuggler 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
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>