taskjuggler 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (571) hide show
  1. data/COPYING +280 -0
  2. data/README +31 -0
  3. data/Rakefile +20 -0
  4. data/benchmarks/UTF-8-Strings.rb +58 -0
  5. data/benchmarks/allocate.tjp +30 -0
  6. data/benchmarks/booking.tjp +62 -0
  7. data/benchmarks/depends.tjp +112 -0
  8. data/benchmarks/htmltaskreport.tjp +45 -0
  9. data/benchmarks/runbench.rb +24 -0
  10. data/bin/tj3 +3 -0
  11. data/bin/tj3man +3 -0
  12. data/doc/classes/AppConfig.html +808 -0
  13. data/doc/classes/Arguments.html +226 -0
  14. data/doc/classes/String.html +395 -0
  15. data/doc/classes/TaskJuggler.html +1358 -0
  16. data/doc/classes/TaskJuggler/Account.html +257 -0
  17. data/doc/classes/TaskJuggler/AccountScenario.html +218 -0
  18. data/doc/classes/TaskJuggler/Allocation.html +419 -0
  19. data/doc/classes/TaskJuggler/AllocationAttribute.html +291 -0
  20. data/doc/classes/TaskJuggler/AttributeBase.html +608 -0
  21. data/doc/classes/TaskJuggler/AttributeDefinition.html +259 -0
  22. data/doc/classes/TaskJuggler/Booking.html +307 -0
  23. data/doc/classes/TaskJuggler/BookingListAttribute.html +263 -0
  24. data/doc/classes/TaskJuggler/BooleanAttribute.html +261 -0
  25. data/doc/classes/TaskJuggler/CSVFile.html +325 -0
  26. data/doc/classes/TaskJuggler/Charge.html +279 -0
  27. data/doc/classes/TaskJuggler/ChargeListAttribute.html +229 -0
  28. data/doc/classes/TaskJuggler/ChargeSet.html +440 -0
  29. data/doc/classes/TaskJuggler/ChargeSetListAttribute.html +276 -0
  30. data/doc/classes/TaskJuggler/ColumnTable.html +260 -0
  31. data/doc/classes/TaskJuggler/DateAttribute.html +194 -0
  32. data/doc/classes/TaskJuggler/DependencyListAttribute.html +267 -0
  33. data/doc/classes/TaskJuggler/DurationAttribute.html +229 -0
  34. data/doc/classes/TaskJuggler/FixnumAttribute.html +194 -0
  35. data/doc/classes/TaskJuggler/FlagListAttribute.html +263 -0
  36. data/doc/classes/TaskJuggler/FloatAttribute.html +229 -0
  37. data/doc/classes/TaskJuggler/GanttChart.html +667 -0
  38. data/doc/classes/TaskJuggler/GanttContainer.html +441 -0
  39. data/doc/classes/TaskJuggler/GanttHeader.html +280 -0
  40. data/doc/classes/TaskJuggler/GanttHeaderScaleItem.html +245 -0
  41. data/doc/classes/TaskJuggler/GanttLine.html +398 -0
  42. data/doc/classes/TaskJuggler/GanttLoadStack.html +327 -0
  43. data/doc/classes/TaskJuggler/GanttMilestone.html +415 -0
  44. data/doc/classes/TaskJuggler/GanttRouter.html +425 -0
  45. data/doc/classes/TaskJuggler/GanttTaskBar.html +429 -0
  46. data/doc/classes/TaskJuggler/HTMLDocument.html +240 -0
  47. data/doc/classes/TaskJuggler/HTMLGraphics.html +231 -0
  48. data/doc/classes/TaskJuggler/Interval.html +552 -0
  49. data/doc/classes/TaskJuggler/IntervalListAttribute.html +267 -0
  50. data/doc/classes/TaskJuggler/KeywordDocumentation.html +796 -0
  51. data/doc/classes/TaskJuggler/Limits.html +416 -0
  52. data/doc/classes/TaskJuggler/Limits/Limit.html +381 -0
  53. data/doc/classes/TaskJuggler/LimitsAttribute.html +261 -0
  54. data/doc/classes/TaskJuggler/Log.html +613 -0
  55. data/doc/classes/TaskJuggler/LogicalAttribute.html +226 -0
  56. data/doc/classes/TaskJuggler/LogicalExpression.html +251 -0
  57. data/doc/classes/TaskJuggler/LogicalFlag.html +229 -0
  58. data/doc/classes/TaskJuggler/LogicalFunction.html +324 -0
  59. data/doc/classes/TaskJuggler/LogicalOperation.html +299 -0
  60. data/doc/classes/TaskJuggler/Macro.html +194 -0
  61. data/doc/classes/TaskJuggler/MacroParser.html +360 -0
  62. data/doc/classes/TaskJuggler/MacroTable.html +366 -0
  63. data/doc/classes/TaskJuggler/Message.html +281 -0
  64. data/doc/classes/TaskJuggler/MessageHandler.html +215 -0
  65. data/doc/classes/TaskJuggler/Project.html +1606 -0
  66. data/doc/classes/TaskJuggler/ProjectFileParser.html +412 -0
  67. data/doc/classes/TaskJuggler/PropertyList.html +597 -0
  68. data/doc/classes/TaskJuggler/PropertySet.html +1200 -0
  69. data/doc/classes/TaskJuggler/PropertyTreeNode.html +1449 -0
  70. data/doc/classes/TaskJuggler/Query.html +600 -0
  71. data/doc/classes/TaskJuggler/RealFormat.html +252 -0
  72. data/doc/classes/TaskJuggler/ReferenceAttribute.html +194 -0
  73. data/doc/classes/TaskJuggler/Report.html +528 -0
  74. data/doc/classes/TaskJuggler/ReportElement.html +1070 -0
  75. data/doc/classes/TaskJuggler/ReportTable.html +497 -0
  76. data/doc/classes/TaskJuggler/ReportTableCell.html +518 -0
  77. data/doc/classes/TaskJuggler/ReportTableColumn.html +364 -0
  78. data/doc/classes/TaskJuggler/ReportTableElement.html +644 -0
  79. data/doc/classes/TaskJuggler/ReportTableLegend.html +343 -0
  80. data/doc/classes/TaskJuggler/ReportTableLine.html +431 -0
  81. data/doc/classes/TaskJuggler/Resource.html +211 -0
  82. data/doc/classes/TaskJuggler/ResourceListAttribute.html +267 -0
  83. data/doc/classes/TaskJuggler/ResourceListRE.html +249 -0
  84. data/doc/classes/TaskJuggler/ResourceScenario.html +1137 -0
  85. data/doc/classes/TaskJuggler/RichText.html +537 -0
  86. data/doc/classes/TaskJuggler/RichTextAttribute.html +229 -0
  87. data/doc/classes/TaskJuggler/RichTextDocument.html +418 -0
  88. data/doc/classes/TaskJuggler/RichTextElement.html +829 -0
  89. data/doc/classes/TaskJuggler/RichTextException.html +212 -0
  90. data/doc/classes/TaskJuggler/RichTextParser.html +317 -0
  91. data/doc/classes/TaskJuggler/RichTextProtocolExample.html +303 -0
  92. data/doc/classes/TaskJuggler/RichTextProtocolHandler.html +194 -0
  93. data/doc/classes/TaskJuggler/RichTextScanner.html +561 -0
  94. data/doc/classes/TaskJuggler/RichTextSnip.html +364 -0
  95. data/doc/classes/TaskJuggler/RichTextSyntaxRules.html +883 -0
  96. data/doc/classes/TaskJuggler/Scenario.html +163 -0
  97. data/doc/classes/TaskJuggler/ScenarioData.html +354 -0
  98. data/doc/classes/TaskJuggler/Scoreboard.html +638 -0
  99. data/doc/classes/TaskJuggler/Shift.html +255 -0
  100. data/doc/classes/TaskJuggler/ShiftAssignment.html +488 -0
  101. data/doc/classes/TaskJuggler/ShiftAssignments.html +715 -0
  102. data/doc/classes/TaskJuggler/ShiftAssignmentsAttribute.html +261 -0
  103. data/doc/classes/TaskJuggler/ShiftScenario.html +282 -0
  104. data/doc/classes/TaskJuggler/SourceFileInfo.html +247 -0
  105. data/doc/classes/TaskJuggler/StringAttribute.html +229 -0
  106. data/doc/classes/TaskJuggler/SymbolAttribute.html +194 -0
  107. data/doc/classes/TaskJuggler/SyntaxReference.html +516 -0
  108. data/doc/classes/TaskJuggler/TOCEntry.html +242 -0
  109. data/doc/classes/TaskJuggler/TableColumnDefinition.html +273 -0
  110. data/doc/classes/TaskJuggler/TableOfContents.html +256 -0
  111. data/doc/classes/TaskJuggler/Task.html +203 -0
  112. data/doc/classes/TaskJuggler/TaskDependency.html +251 -0
  113. data/doc/classes/TaskJuggler/TaskListAttribute.html +267 -0
  114. data/doc/classes/TaskJuggler/TaskListRE.html +250 -0
  115. data/doc/classes/TaskJuggler/TaskScenario.html +2206 -0
  116. data/doc/classes/TaskJuggler/TextParser.html +670 -0
  117. data/doc/classes/TaskJuggler/TextParser/Pattern.html +923 -0
  118. data/doc/classes/TaskJuggler/TextParser/Rule.html +779 -0
  119. data/doc/classes/TaskJuggler/TextParser/StackElement.html +267 -0
  120. data/doc/classes/TaskJuggler/TextParser/TextParserResultArray.html +212 -0
  121. data/doc/classes/TaskJuggler/TextParser/TokenDoc.html +221 -0
  122. data/doc/classes/TaskJuggler/TextScanner.html +708 -0
  123. data/doc/classes/TaskJuggler/TextScanner/BufferStreamHandle.html +355 -0
  124. data/doc/classes/TaskJuggler/TextScanner/FileStreamHandle.html +341 -0
  125. data/doc/classes/TaskJuggler/TextScanner/StreamHandle.html +260 -0
  126. data/doc/classes/TaskJuggler/TjException.html +185 -0
  127. data/doc/classes/TaskJuggler/TjTime.html +1845 -0
  128. data/doc/classes/TaskJuggler/TjpExample.html +310 -0
  129. data/doc/classes/TaskJuggler/TjpExportRE.html +329 -0
  130. data/doc/classes/TaskJuggler/TjpSyntaxRules.html +8928 -0
  131. data/doc/classes/TaskJuggler/UserManual.html +606 -0
  132. data/doc/classes/TaskJuggler/WorkingHours.html +582 -0
  133. data/doc/classes/TaskJuggler/WorkingHoursAttribute.html +284 -0
  134. data/doc/classes/TaskJuggler/XMLBlob.html +207 -0
  135. data/doc/classes/TaskJuggler/XMLComment.html +206 -0
  136. data/doc/classes/TaskJuggler/XMLDocument.html +293 -0
  137. data/doc/classes/TaskJuggler/XMLElement.html +341 -0
  138. data/doc/classes/TaskJuggler/XMLNamedText.html +174 -0
  139. data/doc/classes/TaskJuggler/XMLText.html +221 -0
  140. data/doc/files/COPYING.html +448 -0
  141. data/doc/files/README.html +134 -0
  142. data/doc/files/lib/AccountScenario_rb.html +116 -0
  143. data/doc/files/lib/Account_rb.html +118 -0
  144. data/doc/files/lib/Allocation_rb.html +118 -0
  145. data/doc/files/lib/AppConfig_rb.html +116 -0
  146. data/doc/files/lib/AttributeBase_rb.html +106 -0
  147. data/doc/files/lib/AttributeDefinition_rb.html +106 -0
  148. data/doc/files/lib/Attributes_rb.html +130 -0
  149. data/doc/files/lib/Booking_rb.html +106 -0
  150. data/doc/files/lib/ChargeSet_rb.html +116 -0
  151. data/doc/files/lib/Charge_rb.html +116 -0
  152. data/doc/files/lib/HTMLDocument_rb.html +116 -0
  153. data/doc/files/lib/Interval_rb.html +116 -0
  154. data/doc/files/lib/KeywordDocumentation_rb.html +122 -0
  155. data/doc/files/lib/Limits_rb.html +116 -0
  156. data/doc/files/lib/Log_rb.html +116 -0
  157. data/doc/files/lib/LogicalExpression_rb.html +122 -0
  158. data/doc/files/lib/LogicalFlag_rb.html +116 -0
  159. data/doc/files/lib/LogicalFunction_rb.html +116 -0
  160. data/doc/files/lib/LogicalOperation_rb.html +116 -0
  161. data/doc/files/lib/MacroParser_rb.html +118 -0
  162. data/doc/files/lib/MacroTable_rb.html +122 -0
  163. data/doc/files/lib/MessageHandler_rb.html +106 -0
  164. data/doc/files/lib/Message_rb.html +116 -0
  165. data/doc/files/lib/ProjectFileParser_rb.html +122 -0
  166. data/doc/files/lib/Project_rb.html +148 -0
  167. data/doc/files/lib/PropertyList_rb.html +106 -0
  168. data/doc/files/lib/PropertySet_rb.html +118 -0
  169. data/doc/files/lib/PropertyTreeNode_rb.html +106 -0
  170. data/doc/files/lib/Query_rb.html +116 -0
  171. data/doc/files/lib/RealFormat_rb.html +106 -0
  172. data/doc/files/lib/ResourceScenario_rb.html +116 -0
  173. data/doc/files/lib/Resource_rb.html +118 -0
  174. data/doc/files/lib/RichTextDocument_rb.html +120 -0
  175. data/doc/files/lib/RichTextElement_rb.html +120 -0
  176. data/doc/files/lib/RichTextParser_rb.html +120 -0
  177. data/doc/files/lib/RichTextProtocolExample_rb.html +120 -0
  178. data/doc/files/lib/RichTextProtocolHandler_rb.html +106 -0
  179. data/doc/files/lib/RichTextScanner_rb.html +116 -0
  180. data/doc/files/lib/RichTextSnip_rb.html +118 -0
  181. data/doc/files/lib/RichTextSyntaxRules_rb.html +106 -0
  182. data/doc/files/lib/RichText_rb.html +118 -0
  183. data/doc/files/lib/ScenarioData_rb.html +118 -0
  184. data/doc/files/lib/Scenario_rb.html +116 -0
  185. data/doc/files/lib/Scoreboard_rb.html +106 -0
  186. data/doc/files/lib/ShiftAssignments_rb.html +116 -0
  187. data/doc/files/lib/ShiftScenario_rb.html +116 -0
  188. data/doc/files/lib/Shift_rb.html +118 -0
  189. data/doc/files/lib/SourceFileInfo_rb.html +106 -0
  190. data/doc/files/lib/SyntaxReference_rb.html +122 -0
  191. data/doc/files/lib/TOCEntry_rb.html +118 -0
  192. data/doc/files/lib/TableColumnDefinition_rb.html +106 -0
  193. data/doc/files/lib/TableOfContents_rb.html +118 -0
  194. data/doc/files/lib/TaskDependency_rb.html +106 -0
  195. data/doc/files/lib/TaskJuggler_rb.html +120 -0
  196. data/doc/files/lib/TaskScenario_rb.html +116 -0
  197. data/doc/files/lib/Task_rb.html +118 -0
  198. data/doc/files/lib/TextParser/Pattern_rb.html +116 -0
  199. data/doc/files/lib/TextParser/Rule_rb.html +106 -0
  200. data/doc/files/lib/TextParser/StackElement_rb.html +106 -0
  201. data/doc/files/lib/TextParser/TokenDoc_rb.html +106 -0
  202. data/doc/files/lib/TextParser_rb.html +124 -0
  203. data/doc/files/lib/TextScanner_rb.html +128 -0
  204. data/doc/files/lib/Tj3Config_rb.html +118 -0
  205. data/doc/files/lib/TjException_rb.html +106 -0
  206. data/doc/files/lib/TjTime_rb.html +118 -0
  207. data/doc/files/lib/TjpExample_rb.html +116 -0
  208. data/doc/files/lib/TjpSyntaxRules_rb.html +106 -0
  209. data/doc/files/lib/UTF8String_rb.html +132 -0
  210. data/doc/files/lib/UserManual_rb.html +124 -0
  211. data/doc/files/lib/WorkingHours_rb.html +116 -0
  212. data/doc/files/lib/XMLDocument_rb.html +116 -0
  213. data/doc/files/lib/XMLElement_rb.html +116 -0
  214. data/doc/files/lib/reports/CSVFile_rb.html +116 -0
  215. data/doc/files/lib/reports/ColumnTable_rb.html +116 -0
  216. data/doc/files/lib/reports/GanttChart_rb.html +122 -0
  217. data/doc/files/lib/reports/GanttContainer_rb.html +116 -0
  218. data/doc/files/lib/reports/GanttHeaderScaleItem_rb.html +106 -0
  219. data/doc/files/lib/reports/GanttHeader_rb.html +116 -0
  220. data/doc/files/lib/reports/GanttLine_rb.html +126 -0
  221. data/doc/files/lib/reports/GanttLoadStack_rb.html +116 -0
  222. data/doc/files/lib/reports/GanttMilestone_rb.html +116 -0
  223. data/doc/files/lib/reports/GanttRouter_rb.html +106 -0
  224. data/doc/files/lib/reports/GanttTaskBar_rb.html +116 -0
  225. data/doc/files/lib/reports/HTMLGraphics_rb.html +106 -0
  226. data/doc/files/lib/reports/ReportElement_rb.html +118 -0
  227. data/doc/files/lib/reports/ReportTableCell_rb.html +106 -0
  228. data/doc/files/lib/reports/ReportTableColumn_rb.html +106 -0
  229. data/doc/files/lib/reports/ReportTableElement_rb.html +122 -0
  230. data/doc/files/lib/reports/ReportTableLegend_rb.html +106 -0
  231. data/doc/files/lib/reports/ReportTableLine_rb.html +116 -0
  232. data/doc/files/lib/reports/ReportTable_rb.html +118 -0
  233. data/doc/files/lib/reports/Report_rb.html +126 -0
  234. data/doc/files/lib/reports/ResourceListRE_rb.html +122 -0
  235. data/doc/files/lib/reports/TaskListRE_rb.html +122 -0
  236. data/doc/files/lib/reports/TjpExportRE_rb.html +116 -0
  237. data/doc/files/lib/taskjuggler3_rb.html +276 -0
  238. data/doc/files/lib/tj3man_rb.html +189 -0
  239. data/doc/fr_class_index.html +285 -0
  240. data/doc/fr_file_index.html +223 -0
  241. data/doc/fr_method_index.html +1953 -0
  242. data/doc/index.html +21 -0
  243. data/doc/rdoc-style.css +299 -0
  244. data/examples/tutorial.tjp +361 -0
  245. data/gem_spec.rb +30 -0
  246. data/lib/Account.rb +50 -0
  247. data/lib/AccountScenario.rb +39 -0
  248. data/lib/Allocation.rb +102 -0
  249. data/lib/AppConfig.rb +134 -0
  250. data/lib/AttributeBase.rb +131 -0
  251. data/lib/AttributeDefinition.rb +47 -0
  252. data/lib/Attributes.rb +478 -0
  253. data/lib/BatchProcessor.rb +209 -0
  254. data/lib/Booking.rb +59 -0
  255. data/lib/Charge.rb +71 -0
  256. data/lib/ChargeSet.rb +126 -0
  257. data/lib/HTMLDocument.rb +59 -0
  258. data/lib/Interval.rb +127 -0
  259. data/lib/KeywordDocumentation.rb +560 -0
  260. data/lib/Limits.rb +219 -0
  261. data/lib/Log.rb +160 -0
  262. data/lib/LogicalExpression.rb +71 -0
  263. data/lib/LogicalFlag.rb +34 -0
  264. data/lib/LogicalFunction.rb +102 -0
  265. data/lib/LogicalOperation.rb +118 -0
  266. data/lib/MacroParser.rb +77 -0
  267. data/lib/MacroTable.rb +84 -0
  268. data/lib/Message.rb +56 -0
  269. data/lib/MessageHandler.rb +34 -0
  270. data/lib/Project.rb +662 -0
  271. data/lib/ProjectFileParser.rb +333 -0
  272. data/lib/PropertyList.rb +181 -0
  273. data/lib/PropertySet.rb +304 -0
  274. data/lib/PropertyTreeNode.rb +461 -0
  275. data/lib/Query.rb +227 -0
  276. data/lib/RealFormat.rb +73 -0
  277. data/lib/Resource.rb +42 -0
  278. data/lib/ResourceScenario.rb +511 -0
  279. data/lib/RichText.rb +147 -0
  280. data/lib/RichTextDocument.rb +139 -0
  281. data/lib/RichTextElement.rb +391 -0
  282. data/lib/RichTextParser.rb +66 -0
  283. data/lib/RichTextProtocolExample.rb +65 -0
  284. data/lib/RichTextProtocolHandler.rb +35 -0
  285. data/lib/RichTextScanner.rb +390 -0
  286. data/lib/RichTextSnip.rb +104 -0
  287. data/lib/RichTextSyntaxRules.rb +265 -0
  288. data/lib/Scenario.rb +27 -0
  289. data/lib/ScenarioData.rb +65 -0
  290. data/lib/Scoreboard.rb +141 -0
  291. data/lib/Shift.rb +48 -0
  292. data/lib/ShiftAssignments.rb +291 -0
  293. data/lib/ShiftScenario.rb +46 -0
  294. data/lib/SourceFileInfo.rb +37 -0
  295. data/lib/SyntaxReference.rb +284 -0
  296. data/lib/TOCEntry.rb +76 -0
  297. data/lib/TableColumnDefinition.rb +54 -0
  298. data/lib/TableOfContents.rb +46 -0
  299. data/lib/Task.rb +37 -0
  300. data/lib/TaskDependency.rb +39 -0
  301. data/lib/TaskJuggler.rb +84 -0
  302. data/lib/TaskScenario.rb +1622 -0
  303. data/lib/TextParser.rb +416 -0
  304. data/lib/TextParser/Pattern.rb +263 -0
  305. data/lib/TextParser/Rule.rb +171 -0
  306. data/lib/TextParser/StackElement.rb +45 -0
  307. data/lib/TextParser/TokenDoc.rb +38 -0
  308. data/lib/TextScanner.rb +682 -0
  309. data/lib/Tj3Config.rb +27 -0
  310. data/lib/TjException.rb +27 -0
  311. data/lib/TjTime.rb +395 -0
  312. data/lib/TjpExample.rb +119 -0
  313. data/lib/TjpSyntaxRules.rb +4022 -0
  314. data/lib/UTF8String.rb +100 -0
  315. data/lib/UserManual.rb +282 -0
  316. data/lib/WorkingHours.rb +323 -0
  317. data/lib/XMLDocument.rb +54 -0
  318. data/lib/XMLElement.rb +175 -0
  319. data/lib/reports/CSVFile.rb +146 -0
  320. data/lib/reports/ColumnTable.rb +66 -0
  321. data/lib/reports/GanttChart.rb +308 -0
  322. data/lib/reports/GanttContainer.rb +107 -0
  323. data/lib/reports/GanttHeader.rb +141 -0
  324. data/lib/reports/GanttHeaderScaleItem.rb +42 -0
  325. data/lib/reports/GanttLine.rb +329 -0
  326. data/lib/reports/GanttLoadStack.rb +113 -0
  327. data/lib/reports/GanttMilestone.rb +80 -0
  328. data/lib/reports/GanttRouter.rb +375 -0
  329. data/lib/reports/GanttTaskBar.rb +95 -0
  330. data/lib/reports/HTMLGraphics.rb +65 -0
  331. data/lib/reports/Report.rb +344 -0
  332. data/lib/reports/ReportElement.rb +427 -0
  333. data/lib/reports/ReportTable.rb +144 -0
  334. data/lib/reports/ReportTableCell.rb +142 -0
  335. data/lib/reports/ReportTableColumn.rb +82 -0
  336. data/lib/reports/ReportTableElement.rb +852 -0
  337. data/lib/reports/ReportTableLegend.rb +167 -0
  338. data/lib/reports/ReportTableLine.rb +87 -0
  339. data/lib/reports/ResourceListRE.rb +72 -0
  340. data/lib/reports/TaskListRE.rb +73 -0
  341. data/lib/reports/TjpExportRE.rb +394 -0
  342. data/lib/taskjuggler3.rb +106 -0
  343. data/lib/tj3man.rb +88 -0
  344. data/manual/Day_To_Day_Juggling +168 -0
  345. data/manual/Getting_Started +61 -0
  346. data/manual/How_To_Contribute +185 -0
  347. data/manual/Installation +68 -0
  348. data/manual/Intro +102 -0
  349. data/manual/Reporting_Bugs +26 -0
  350. data/manual/Rich_Text_Attributes +90 -0
  351. data/manual/TaskJuggler_2x_Migration +40 -0
  352. data/manual/Tutorial +579 -0
  353. data/manual/fdl +450 -0
  354. data/prj_cfg.rb +43 -0
  355. data/setup.rb +1585 -0
  356. data/tasks/csts.rake +72 -0
  357. data/tasks/gem.rake +14 -0
  358. data/tasks/manual.rake +10 -0
  359. data/tasks/missing.rake +21 -0
  360. data/tasks/rcov.rake +14 -0
  361. data/tasks/rdoc.rake +17 -0
  362. data/tasks/rexml_fix.rb +16 -0
  363. data/tasks/rexml_fix_19.rb +49 -0
  364. data/tasks/show.rake +21 -0
  365. data/tasks/stats.rake +25 -0
  366. data/tasks/test.rake +11 -0
  367. data/test/MessageChecker.rb +53 -0
  368. data/test/TestSuite/CSV-Reports/celltext-Reference.csv +14 -0
  369. data/test/TestSuite/CSV-Reports/celltext.tjp +7 -0
  370. data/test/TestSuite/CSV-Reports/genrefs +6 -0
  371. data/test/TestSuite/CSV-Reports/project-1.tji +57 -0
  372. data/test/TestSuite/CSV-Reports/resourcereport-Reference.csv +4 -0
  373. data/test/TestSuite/CSV-Reports/resourcereport.tjp +10 -0
  374. data/test/TestSuite/CSV-Reports/resourcereport_with_tasks-Reference.csv +22 -0
  375. data/test/TestSuite/CSV-Reports/resourcereport_with_tasks.tjp +11 -0
  376. data/test/TestSuite/CSV-Reports/sortByTree-Reference.csv +14 -0
  377. data/test/TestSuite/CSV-Reports/sortByTree.tjp +8 -0
  378. data/test/TestSuite/CSV-Reports/sortBy_duration.down-Reference.csv +14 -0
  379. data/test/TestSuite/CSV-Reports/sortBy_duration.down.tjp +10 -0
  380. data/test/TestSuite/CSV-Reports/sortBy_effort.up-Reference.csv +14 -0
  381. data/test/TestSuite/CSV-Reports/sortBy_effort.up.tjp +10 -0
  382. data/test/TestSuite/CSV-Reports/sortBy_plan.start.down-Reference.csv +14 -0
  383. data/test/TestSuite/CSV-Reports/sortBy_plan.start.down.tjp +10 -0
  384. data/test/TestSuite/CSV-Reports/taskreport-Reference.csv +14 -0
  385. data/test/TestSuite/CSV-Reports/taskreport.tjp +10 -0
  386. data/test/TestSuite/CSV-Reports/taskreport_with_resources-Reference.csv +24 -0
  387. data/test/TestSuite/CSV-Reports/taskreport_with_resources.tjp +11 -0
  388. data/test/TestSuite/Scheduler/Correct/Allocate.tjp +86 -0
  389. data/test/TestSuite/Scheduler/Correct/AutomaticMilestones.tjp +63 -0
  390. data/test/TestSuite/Scheduler/Correct/Booking.tjp +161 -0
  391. data/test/TestSuite/Scheduler/Correct/Depends.tjp +50 -0
  392. data/test/TestSuite/Scheduler/Correct/Duration.tjp +34 -0
  393. data/test/TestSuite/Scheduler/Correct/InheritStartEnd.tjp +129 -0
  394. data/test/TestSuite/Scheduler/Correct/Limits.tjp +81 -0
  395. data/test/TestSuite/Scheduler/Correct/MultipleMandatories.tjp +43 -0
  396. data/test/TestSuite/Scheduler/Correct/Optimize-1.tjp +28 -0
  397. data/test/TestSuite/Scheduler/Correct/Optimize-2.tjp +33 -0
  398. data/test/TestSuite/Scheduler/Correct/Optimize-3.tjp +33 -0
  399. data/test/TestSuite/Scheduler/Correct/Optimize-4.tjp +34 -0
  400. data/test/TestSuite/Scheduler/Correct/Optimize-5.tjp +62 -0
  401. data/test/TestSuite/Scheduler/Correct/Precedes.tjp +50 -0
  402. data/test/TestSuite/Scheduler/Correct/Shift.tjp +102 -0
  403. data/test/TestSuite/Scheduler/Errors/account_no_leaf.tjp +13 -0
  404. data/test/TestSuite/Scheduler/Errors/booking_conflict.tjp +10 -0
  405. data/test/TestSuite/Scheduler/Errors/booking_no_duty.tjp +9 -0
  406. data/test/TestSuite/Scheduler/Errors/booking_on_vacation.tjp +9 -0
  407. data/test/TestSuite/Scheduler/Errors/container_booking.tjp +14 -0
  408. data/test/TestSuite/Scheduler/Errors/container_duration.tjp +11 -0
  409. data/test/TestSuite/Scheduler/Errors/effort_no_allocations.tjp +7 -0
  410. data/test/TestSuite/Scheduler/Errors/loop_detected_1.tjp +19 -0
  411. data/test/TestSuite/Scheduler/Errors/loop_detected_10.tjp +36 -0
  412. data/test/TestSuite/Scheduler/Errors/loop_detected_11.tjp +27 -0
  413. data/test/TestSuite/Scheduler/Errors/loop_detected_12.tjp +20 -0
  414. data/test/TestSuite/Scheduler/Errors/loop_detected_13.tjp +27 -0
  415. data/test/TestSuite/Scheduler/Errors/loop_detected_14.tjp +26 -0
  416. data/test/TestSuite/Scheduler/Errors/loop_detected_2.tjp +24 -0
  417. data/test/TestSuite/Scheduler/Errors/loop_detected_3.tjp +18 -0
  418. data/test/TestSuite/Scheduler/Errors/loop_detected_4.tjp +36 -0
  419. data/test/TestSuite/Scheduler/Errors/loop_detected_5.tjp +37 -0
  420. data/test/TestSuite/Scheduler/Errors/loop_detected_6.tjp +35 -0
  421. data/test/TestSuite/Scheduler/Errors/loop_detected_7.tjp +46 -0
  422. data/test/TestSuite/Scheduler/Errors/loop_detected_8.tjp +51 -0
  423. data/test/TestSuite/Scheduler/Errors/loop_detected_9.tjp +20 -0
  424. data/test/TestSuite/Scheduler/Errors/maxend.tjp +8 -0
  425. data/test/TestSuite/Scheduler/Errors/maxstart.tjp +8 -0
  426. data/test/TestSuite/Scheduler/Errors/milestone_booking.tjp +10 -0
  427. data/test/TestSuite/Scheduler/Errors/milestone_duration.tjp +8 -0
  428. data/test/TestSuite/Scheduler/Errors/milestone_start_end.tjp +8 -0
  429. data/test/TestSuite/Scheduler/Errors/minend.tjp +8 -0
  430. data/test/TestSuite/Scheduler/Errors/minstart.tjp +8 -0
  431. data/test/TestSuite/Scheduler/Errors/multiple_durations.tjp +11 -0
  432. data/test/TestSuite/Scheduler/Errors/no_tasks.tjp +6 -0
  433. data/test/TestSuite/Scheduler/Errors/not_scheduled.tjp +8 -0
  434. data/test/TestSuite/Scheduler/Errors/task_depend_child.tjp +10 -0
  435. data/test/TestSuite/Scheduler/Errors/task_depend_multi.tjp +13 -0
  436. data/test/TestSuite/Scheduler/Errors/task_depend_parent.tjp +11 -0
  437. data/test/TestSuite/Scheduler/Errors/task_depend_self.tjp +10 -0
  438. data/test/TestSuite/Scheduler/Errors/task_depend_unknown.tjp +10 -0
  439. data/test/TestSuite/Scheduler/Errors/task_overspecified_1.tjp +9 -0
  440. data/test/TestSuite/Scheduler/Errors/task_overspecified_2.tjp +14 -0
  441. data/test/TestSuite/Scheduler/Errors/task_overspecified_3.tjp +14 -0
  442. data/test/TestSuite/Scheduler/Errors/task_underspecified_1.tjp +8 -0
  443. data/test/TestSuite/Scheduler/Errors/task_underspecified_2.tjp +8 -0
  444. data/test/TestSuite/Scheduler/Errors/task_underspecified_3.tjp +9 -0
  445. data/test/TestSuite/Syntax/Correct/Account.tjp +53 -0
  446. data/test/TestSuite/Syntax/Correct/Allocate-1.tjp +24 -0
  447. data/test/TestSuite/Syntax/Correct/Alternative.tjp +13 -0
  448. data/test/TestSuite/Syntax/Correct/AutoMacros.tjp +14 -0
  449. data/test/TestSuite/Syntax/Correct/Booking.tjp +26 -0
  450. data/test/TestSuite/Syntax/Correct/Caption.tjp +33 -0
  451. data/test/TestSuite/Syntax/Correct/Celltext.tjp +28 -0
  452. data/test/TestSuite/Syntax/Correct/Comments.tjp +29 -0
  453. data/test/TestSuite/Syntax/Correct/Complete.tjp +16 -0
  454. data/test/TestSuite/Syntax/Correct/CompletedWork.tji +20 -0
  455. data/test/TestSuite/Syntax/Correct/CriticalPath.tjp +31 -0
  456. data/test/TestSuite/Syntax/Correct/Currencyformat.tjp +12 -0
  457. data/test/TestSuite/Syntax/Correct/CustomAttributes.tjp +14 -0
  458. data/test/TestSuite/Syntax/Correct/Depends1.tjp +22 -0
  459. data/test/TestSuite/Syntax/Correct/Durations.tjp +29 -0
  460. data/test/TestSuite/Syntax/Correct/Efficiency.tjp +19 -0
  461. data/test/TestSuite/Syntax/Correct/Export.tjp +40 -0
  462. data/test/TestSuite/Syntax/Correct/Flags.tjp +32 -0
  463. data/test/TestSuite/Syntax/Correct/Freeze.tjp +28 -0
  464. data/test/TestSuite/Syntax/Correct/Gap.tjp +15 -0
  465. data/test/TestSuite/Syntax/Correct/HtmlTaskReport.tjp +33 -0
  466. data/test/TestSuite/Syntax/Correct/Limits-1.tjp +71 -0
  467. data/test/TestSuite/Syntax/Correct/LoadUnits.tjp +31 -0
  468. data/test/TestSuite/Syntax/Correct/Macro-1.tjp +19 -0
  469. data/test/TestSuite/Syntax/Correct/Mandatory.tjp +17 -0
  470. data/test/TestSuite/Syntax/Correct/Milestone.tjp +12 -0
  471. data/test/TestSuite/Syntax/Correct/MinMax.tjp +17 -0
  472. data/test/TestSuite/Syntax/Correct/Numberformat.tjp +12 -0
  473. data/test/TestSuite/Syntax/Correct/Period.tjp +16 -0
  474. data/test/TestSuite/Syntax/Correct/Persistent.tjp +11 -0
  475. data/test/TestSuite/Syntax/Correct/Precedes1.tjp +17 -0
  476. data/test/TestSuite/Syntax/Correct/Priority.tjp +30 -0
  477. data/test/TestSuite/Syntax/Correct/Project.tjp +21 -0
  478. data/test/TestSuite/Syntax/Correct/ProjectIDs.tjp +23 -0
  479. data/test/TestSuite/Syntax/Correct/RawHTML.tjp +29 -0
  480. data/test/TestSuite/Syntax/Correct/Reports.tjp +54 -0
  481. data/test/TestSuite/Syntax/Correct/Resource.tjp +20 -0
  482. data/test/TestSuite/Syntax/Correct/Responsible.tjp +16 -0
  483. data/test/TestSuite/Syntax/Correct/Scenario.tjp +15 -0
  484. data/test/TestSuite/Syntax/Correct/Scheduling.tjp +26 -0
  485. data/test/TestSuite/Syntax/Correct/Select.tjp +27 -0
  486. data/test/TestSuite/Syntax/Correct/Shift.tjp +55 -0
  487. data/test/TestSuite/Syntax/Correct/Simple.tjp +25 -0
  488. data/test/TestSuite/Syntax/Correct/String.tjp +12 -0
  489. data/test/TestSuite/Syntax/Correct/Supplement.tjp +24 -0
  490. data/test/TestSuite/Syntax/Correct/TaskRoot.tjp +34 -0
  491. data/test/TestSuite/Syntax/Correct/TimeFrame.tjp +19 -0
  492. data/test/TestSuite/Syntax/Correct/Timezone.tjp +8 -0
  493. data/test/TestSuite/Syntax/Correct/Vacation.tjp +33 -0
  494. data/test/TestSuite/Syntax/Correct/csvtest +16 -0
  495. data/test/TestSuite/Syntax/Correct/manual2example.rb +24 -0
  496. data/test/TestSuite/Syntax/Correct/tutorial.tjp +485 -0
  497. data/test/TestSuite/Syntax/Errors/bad_include.tjp +11 -0
  498. data/test/TestSuite/Syntax/Errors/booking_group.tjp +14 -0
  499. data/test/TestSuite/Syntax/Errors/booking_milestone.tjp +13 -0
  500. data/test/TestSuite/Syntax/Errors/booking_no_leaf.tjp +13 -0
  501. data/test/TestSuite/Syntax/Errors/chargeset.tjp +14 -0
  502. data/test/TestSuite/Syntax/Errors/chargeset_master.tjp +15 -0
  503. data/test/TestSuite/Syntax/Errors/container_attribute.tjp +13 -0
  504. data/test/TestSuite/Syntax/Errors/cost_acct_no_top.tjp +24 -0
  505. data/test/TestSuite/Syntax/Errors/cost_rev_same.tjp +24 -0
  506. data/test/TestSuite/Syntax/Errors/date_in_range.tjp +7 -0
  507. data/test/TestSuite/Syntax/Errors/effort_zero.tjp +8 -0
  508. data/test/TestSuite/Syntax/Errors/empty.tjp +1 -0
  509. data/test/TestSuite/Syntax/Errors/export_bad_extn.tjp +9 -0
  510. data/test/TestSuite/Syntax/Errors/extend_id_cap.tjp +7 -0
  511. data/test/TestSuite/Syntax/Errors/interval_end_in_range.tjp +7 -0
  512. data/test/TestSuite/Syntax/Errors/interval_start_in_range.tjp +7 -0
  513. data/test/TestSuite/Syntax/Errors/leaf_resource_id_expected.tjp +12 -0
  514. data/test/TestSuite/Syntax/Errors/misaligned_date.tjp +7 -0
  515. data/test/TestSuite/Syntax/Errors/no_csv_suffix.tjp +10 -0
  516. data/test/TestSuite/Syntax/Errors/no_html_suffix.tjp +10 -0
  517. data/test/TestSuite/Syntax/Errors/operand_attribute.tjp +11 -0
  518. data/test/TestSuite/Syntax/Errors/operand_unkn_flag.tjp +11 -0
  519. data/test/TestSuite/Syntax/Errors/operand_unkn_scen.tjp +11 -0
  520. data/test/TestSuite/Syntax/Errors/overtime_range.tjp +13 -0
  521. data/test/TestSuite/Syntax/Errors/purge_no_list.tjp +8 -0
  522. data/test/TestSuite/Syntax/Errors/purge_unknown_id.tjp +8 -0
  523. data/test/TestSuite/Syntax/Errors/report_end.tjp +10 -0
  524. data/test/TestSuite/Syntax/Errors/report_redifinition.tjp +10 -0
  525. data/test/TestSuite/Syntax/Errors/report_start.tjp +10 -0
  526. data/test/TestSuite/Syntax/Errors/resource_exists.tjp +7 -0
  527. data/test/TestSuite/Syntax/Errors/resource_id_expected.tjp +8 -0
  528. data/test/TestSuite/Syntax/Errors/rev_acct_no_top.tjp +24 -0
  529. data/test/TestSuite/Syntax/Errors/scenario_exists.tjp +7 -0
  530. data/test/TestSuite/Syntax/Errors/shift_assignment_overlap.tjp +15 -0
  531. data/test/TestSuite/Syntax/Errors/shift_exists.tjp +7 -0
  532. data/test/TestSuite/Syntax/Errors/shift_id_expected.tjp +7 -0
  533. data/test/TestSuite/Syntax/Errors/sloppy_range.tjp +13 -0
  534. data/test/TestSuite/Syntax/Errors/sort_direction.tjp +11 -0
  535. data/test/TestSuite/Syntax/Errors/sort_unknown_scen.tjp +11 -0
  536. data/test/TestSuite/Syntax/Errors/sorting_crit_exptd1.tjp +11 -0
  537. data/test/TestSuite/Syntax/Errors/sorting_crit_exptd2.tjp +11 -0
  538. data/test/TestSuite/Syntax/Errors/sorting_wbs.tjp +11 -0
  539. data/test/TestSuite/Syntax/Errors/start_before_end1.tjp +7 -0
  540. data/test/TestSuite/Syntax/Errors/start_before_end2.tjp +6 -0
  541. data/test/TestSuite/Syntax/Errors/task_complete.tjp +8 -0
  542. data/test/TestSuite/Syntax/Errors/task_exists.tjp +7 -0
  543. data/test/TestSuite/Syntax/Errors/task_priority.tjp +8 -0
  544. data/test/TestSuite/Syntax/Errors/task_without_chargeset.tjp +9 -0
  545. data/test/TestSuite/Syntax/Errors/time_interval.tjp +12 -0
  546. data/test/TestSuite/Syntax/Errors/too_many_bangs.tjp +10 -0
  547. data/test/TestSuite/Syntax/Errors/undecl_flag.tjp +6 -0
  548. data/test/TestSuite/Syntax/Errors/unknown_projectid.tjp +7 -0
  549. data/test/TestSuite/Syntax/Errors/unknown_scenario_id.tjp +6 -0
  550. data/test/TestSuite/Syntax/Errors/unknown_scenario_idx.tjp +11 -0
  551. data/test/TestSuite/Syntax/Errors/unknown_task.tjp +10 -0
  552. data/test/all.rb +31 -0
  553. data/test/test_BatchProcessor.rb +54 -0
  554. data/test/test_CSV-Reports.rb +101 -0
  555. data/test/test_Limits.rb +104 -0
  556. data/test/test_LogicalExpression.rb +110 -0
  557. data/test/test_MacroTable.rb +51 -0
  558. data/test/test_Project.rb +57 -0
  559. data/test/test_PropertySet.rb +71 -0
  560. data/test/test_Query.rb +83 -0
  561. data/test/test_RealFormat.rb +83 -0
  562. data/test/test_RichText.rb +869 -0
  563. data/test/test_Scheduler.rb +42 -0
  564. data/test/test_ShiftAssignments.rb +77 -0
  565. data/test/test_Syntax.rb +41 -0
  566. data/test/test_TextScanner.rb +95 -0
  567. data/test/test_TjTime.rb +114 -0
  568. data/test/test_TjpExample.rb +169 -0
  569. data/test/test_UTF8String.rb +84 -0
  570. data/test/test_WorkingHours.rb +56 -0
  571. metadata +649 -0
@@ -0,0 +1,416 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = TextParser.rb -- The TaskJuggler III Project Management Software
5
+ #
6
+ # Copyright (c) 2006, 2007, 2008, 2009 by Chris Schlaeger <cs@kde.org>
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of version 2 of the GNU General Public License as
10
+ # published by the Free Software Foundation.
11
+ #
12
+
13
+ require 'TextParser/Pattern'
14
+ require 'TextParser/Rule'
15
+ require 'TextParser/StackElement'
16
+ require 'TjException'
17
+ require 'Log'
18
+
19
+ class TaskJuggler
20
+
21
+ # The TextParser implements a regular LALR parser. But it uses a recursive
22
+ # rule traversor instead of the more commonly found state machine generated by
23
+ # yacc-like tools. Since stack depths is not really an issue with a Ruby
24
+ # implementation this approach has one big advantage. The syntax of the parser
25
+ # can be modified during parsing. This allows support for languages that can
26
+ # extend themself. The TaskJuggler syntax is such an beast. Traditional yacc
27
+ # generated parsers would fail with such a syntax.
28
+ #
29
+ # This class is just a base class. A complete parser would derive from this
30
+ # class and implement the rule set and the functions _nextToken()_ and
31
+ # _returnToken()_. It also needs to set the array _variables_ to declare all
32
+ # variables ($SOMENAME) that the scanner may deliver.
33
+ #
34
+ # To describe the syntax the functions TextParser#pattern, TextParser#optional
35
+ # and TextParser#repeatable can be used. When the rule set is changed during
36
+ # parsing, TextParser#updateParserTables must be called to make the changes
37
+ # effective. The parser can also document the syntax automatically. To
38
+ # document a pattern, the functions TextParser#doc, TextParser#descr,
39
+ # TextParser#also and TextParser#arg can be used.
40
+ #
41
+ # To start parsing the input the function TextParser#parse needs to be called
42
+ # with the name of the start rule.
43
+ class TextParser
44
+
45
+ # Utility class so that we can distinguish Array results from the Array
46
+ # containing the results of a repeatable rule.
47
+ class TextParserResultArray < Array
48
+
49
+ def initialize
50
+ super
51
+ end
52
+
53
+ # If there is a repeatable rule that contains another repeatable loop, the
54
+ # result of the inner rule is an Array that gets put into another Array by
55
+ # the outer rule. In this case, the inner Array can be merged with the
56
+ # outer Array.
57
+ def <<(arg)
58
+ if arg.is_a?(TextParserResultArray)
59
+ self.concat(arg)
60
+ else
61
+ super
62
+ end
63
+ end
64
+
65
+ end
66
+
67
+ attr_reader :rules
68
+
69
+ # Create a new TextParser object.
70
+ def initialize
71
+ @rules = { }
72
+ # Array to hold the token types that the scanner can return.
73
+ @variables = []
74
+ # The currently processed rule.
75
+ @cr = nil
76
+ # If set to a value larger than 0 debug output will be generated.
77
+ @@debug = 30
78
+ end
79
+
80
+ # Call all methods that start with 'rule_' to initialize the rules.
81
+ def initRules
82
+ methods.each do |m|
83
+ if m[0, 5] == 'rule_'
84
+ # Create a new rule with the suffix of the function name as name.
85
+ newRule(m[5..-1])
86
+ # Call the function.
87
+ send(m)
88
+ end
89
+ end
90
+ end
91
+
92
+ # Add a new rule to the rule set. _name_ must be a unique identifier. The
93
+ # function also sets the class variable @cr to the new rule. Subsequent
94
+ # calls to TextParser#pattern, TextParser#optional or
95
+ # TextParser#repeatable will then implicitely operate on the most recently
96
+ # added rule.
97
+ def newRule(name)
98
+ raise "Fatal Error: Rule #{name} already exists" if @rules.has_key?(name)
99
+
100
+ @rules[name] = @cr = TextParser::Rule.new(name)
101
+ end
102
+
103
+ # Add a new pattern to the most recently added rule. _tokens_ is an array of
104
+ # strings that specify the syntax elements of the pattern. Each token must
105
+ # start with an character that identifies the type of the token. The
106
+ # following types are supported.
107
+ #
108
+ # * ! a reference to another rule
109
+ # * $ a variable token as delivered by the scanner
110
+ # * _ a literal token.
111
+ #
112
+ # _func_ is a Proc object that is called whenever the parser has completed
113
+ # the processing of this rule.
114
+ def pattern(tokens, func = nil)
115
+ @cr.addPattern(TextParser::Pattern.new(tokens, func))
116
+ end
117
+
118
+ # Identify the patterns of the most recently added rule as optional syntax
119
+ # elements.
120
+ def optional
121
+ @cr.setOptional
122
+ end
123
+
124
+ # Identify the patterns of the most recently added rule as repeatable syntax
125
+ # elements.
126
+ def repeatable
127
+ @cr.setRepeatable
128
+ end
129
+
130
+ # This function needs to be called whenever new rules or patterns have been
131
+ # added and before the next call to TextParser#parse.
132
+ def updateParserTables
133
+ @rules.each_value { |rule| rule.transitions = {} }
134
+ @rules.each_value do |rule|
135
+ getTransitions(rule)
136
+ checkRule(rule)
137
+ end
138
+ end
139
+
140
+ # To parse the input this function needs to be called with the name of the
141
+ # rule to start with. It returns the result of the processing function of
142
+ # the top-level parser rule that was specified by _ruleName_.
143
+ def parse(ruleName, enforceEndOfFile = true)
144
+ @stack = []
145
+ @@expectedTokens = []
146
+ updateParserTables
147
+ begin
148
+ result = parseRule(@rules[ruleName])
149
+ rescue TjException
150
+ # error('parse_error', $!.message)
151
+ return nil
152
+ end
153
+
154
+ result
155
+ end
156
+
157
+ # Return the SourceFileInfo of the TextScanner at the beginning of the
158
+ # currently processed TextParser::Rule. Or return nil if we don't have a
159
+ # current position.
160
+ def sourceFileInfo
161
+ return nil if @stack.empty?
162
+ @stack.last.sourceFileInfo
163
+ end
164
+
165
+ def matchingRules(keyword)
166
+ matches = []
167
+ @rules.each do |name, rule|
168
+ patIdx = rule.matchingPatternIndex('_' + keyword)
169
+ matches << [ rule, patIdx ] if patIdx
170
+ end
171
+ matches
172
+ end
173
+
174
+ def error(id, text, property = nil)
175
+ @scanner.error(id, text, property)
176
+ end
177
+
178
+ private
179
+
180
+ # getTransitions recursively determines all possible target tokens
181
+ # that the _rule_ matches. A target token can either be a fixed token
182
+ # (prefixed with _), a variable token (prefixed with $) or an end token
183
+ # (just a .). The list of found target tokens is stored in the _transitions_
184
+ # list of the rule. For each rule pattern we store the transitions for this
185
+ # pattern in a token -> rule hash.
186
+ def getTransitions(rule)
187
+ # If we have processed this rule before we can just return a copy
188
+ # of the transitions of this rule. This avoids endless recursions.
189
+ return rule.transitions.clone unless rule.transitions.empty?
190
+
191
+ rule.transitions = []
192
+ rule.patterns.each do |pat|
193
+ allTokensOptional = true
194
+ transitions = { }
195
+ pat.each do |token|
196
+ tokenId = token[1..-1]
197
+ if token[0] == ?!
198
+ unless @rules.has_key?(tokenId)
199
+ raise "Fatal Error: Unknown reference to #{tokenId} in pattern " +
200
+ "#{pat} + of rule #{rule.name}"
201
+ end
202
+ refRule = @rules[tokenId]
203
+ # If the referenced rule describes optional content, we need to look
204
+ # at the next token as well.
205
+ res = getTransitions(@rules[tokenId])
206
+ allTokensOptional = false unless refRule.optional?(@rules)
207
+ # Combine the hashes for each pattern into a single hash
208
+ res.each do |pat_i|
209
+ pat_i.each { |tok, r| transitions[tok] = r }
210
+ end
211
+ optional = true if refRule.optional
212
+ elsif '_$.'.include?(token[0])
213
+ transitions[token] = rule
214
+ allTokensOptional = false
215
+ else
216
+ raise 'Fatal Error: Illegal token type specifier used for token' +
217
+ ": #{tokenId}"
218
+ end
219
+ break unless allTokensOptional
220
+ end
221
+ # Make sure that we only have one possible transition for each
222
+ # target.
223
+ transitions.each do |key, value|
224
+ rule.transitions.each do |trans|
225
+ if trans.has_key?(key)
226
+ raise "Fatal Error: Rule #{rule.name} has ambigeous " +
227
+ "transitions for target #{key}"
228
+ end
229
+ end
230
+ end
231
+ rule.transitions << transitions
232
+ end
233
+ rule.transitions.clone
234
+ end
235
+
236
+ def checkRule(rule)
237
+ if rule.patterns.empty?
238
+ raise "Rule #{rule.name} must have at least one pattern"
239
+ end
240
+
241
+ rule.patterns.each do |pat|
242
+ pat.each do |tok|
243
+ type = tok[0]
244
+ token = tok[1..-1]
245
+ if type == ?$
246
+ if @variables.index(token).nil?
247
+ raise "Fatal Error: Illegal variable type #{token} used for " +
248
+ "rule #{rule.name} in pattern '#{pat}'"
249
+ end
250
+ elsif type == ?!
251
+ if @rules[token].nil?
252
+ raise "Fatal Error: Reference to unknown rule #{token} in " +
253
+ "pattern '#{pat}' of rule #{rule.name}"
254
+ end
255
+ end
256
+ end
257
+ end
258
+ end
259
+
260
+ # This function processes the input starting with the syntax description of
261
+ # _rule_. It recursively calls this function whenever the syntax description
262
+ # contains the reference to another rule.
263
+ def parseRule(rule)
264
+ Log.enter('parseRule', "Parsing with rule #{rule.name}")
265
+ result = rule.repeatable ? TextParserResultArray.new : nil
266
+ # Rules can be marked 'repeatable'. This flag will be set to true after
267
+ # the first iteration has been completed.
268
+ repeatMode = false
269
+ loop do
270
+ # At the beginning of a rule we need a token from the input to determine
271
+ # which pattern of the rule needs to be processed.
272
+ begin
273
+ token = nextToken
274
+ Log << "Token: [#{token[0]}][#{token[1]}]"
275
+ rescue TjException
276
+ error('parse_rule1', $!.message)
277
+ end
278
+
279
+ # The scanner cannot differentiate between keywords and identifiers. So
280
+ # whenever an identifier is returned we have to see if we have a
281
+ # matching keyword first. If none is found, then look for normal
282
+ # identifiers.
283
+ if token[0] == 'ID'
284
+ if (patIdx = rule.matchingPatternIndex('_' + token[1])).nil?
285
+ patIdx = rule.matchingPatternIndex("$ID")
286
+ end
287
+ elsif token[0] == 'LITERAL'
288
+ patIdx = rule.matchingPatternIndex('_' + token[1])
289
+ elsif token[0] == false
290
+ patIdx = rule.matchingPatternIndex('.')
291
+ else
292
+ patIdx = rule.matchingPatternIndex('$' + token[0])
293
+ end
294
+
295
+ # If no matching pattern is found for the token we have to check if the
296
+ # rule is optional or we are in repeat mode. If this is the case, return
297
+ # the token back to the scanner. Otherwise we have found a token we
298
+ # cannot handle at this point.
299
+ if patIdx.nil?
300
+ # Append the list of expected tokens to the @@expectedToken array.
301
+ # This may be used in a later rule to provide more details when an
302
+ # error occured.
303
+ rule.transitions.each do |transition|
304
+ keys = transition.keys
305
+ keys.collect! { |key| key[1..-1] }
306
+ @@expectedTokens += keys
307
+ @@expectedTokens.sort!
308
+ end
309
+
310
+ unless rule.optional?(@rules) || repeatMode
311
+ error('unexpctd_token',
312
+ (token[0] != false ?
313
+ "Unexpected token '#{token[1]}' of type '#{token[0]}'. " :
314
+ "Unexpected end of file in #{@scanner.fileName}. ") +
315
+ (@@expectedTokens.length > 1 ?
316
+ "Expecting one of #{@@expectedTokens.join(', ')}" :
317
+ "Expecting #{@@expectedTokens[0]}"))
318
+ end
319
+ returnToken(token)
320
+ Log.exit('parseRule', "Finished rule #{rule.name}")
321
+ return result
322
+ end
323
+
324
+ pattern = rule.pattern(patIdx)
325
+ @stack << TextParser::StackElement.new(rule, pattern.function,
326
+ @scanner.sourceFileInfo)
327
+
328
+ pattern.each do |element|
329
+ # Separate the type and token text for pattern element.
330
+ elType = element[0]
331
+ elToken = element[1..-1]
332
+ if elType == ?!
333
+ # The element is a reference to another rule. Return the token if we
334
+ # still have one and continue with the referenced rule.
335
+ unless token.nil?
336
+ returnToken(token)
337
+ token = nil
338
+ end
339
+ @stack.last.store(parseRule(@rules[elToken]))
340
+ else
341
+ # In case the element is a keyword or variable we have to get a new
342
+ # token if we don't have one anymore.
343
+ if token.nil?
344
+ begin
345
+ token = nextToken
346
+ Log << "Token: [#{token[0]}][#{token[1]}]"
347
+ rescue TjException
348
+ error('parse_rule2', $!.message)
349
+ end
350
+ end
351
+
352
+ if elType == ?_
353
+ # If the element requires a keyword the token must match this
354
+ # keyword.
355
+ if elToken != token[1]
356
+ text = "'#{elToken}' expected but found " +
357
+ "'#{token[1]}' (#{token[0]})."
358
+ unless @@expectedTokens.empty?
359
+ text = "#{@@expectedTokens.join(', ')} or " + text
360
+ end
361
+ error('spec_keywork_expctd', text)
362
+ end
363
+ @stack.last.store(elToken)
364
+ elsif elType == ?.
365
+ if token != [ '.', '<END>' ]
366
+ error('end_expected', 'End expected but found ' +
367
+ "'#{token[1]}' (#{token[0]}).")
368
+ end
369
+ else
370
+ # The token must match the expected variable type.
371
+ if token[0] != elToken
372
+ text = "'#{elToken}' expected but found " +
373
+ "'#{token[1]}' (#{token[0]})."
374
+ unless @@expectedTokens.empty?
375
+ text = "#{@@expectedTokens.join(', ')} or " + text
376
+ end
377
+ error('spec_token_expctd', text)
378
+ end
379
+ # If the element is a variable store the value of the token.
380
+ @stack.last.store(token[1])
381
+ end
382
+ # The token has been consumed. Reset the variable.
383
+ token = nil
384
+ @@expectedTokens = []
385
+ end
386
+ end
387
+
388
+ # Once the complete pattern has been processed we call the processing
389
+ # function for this pattern to operate on the value array. Then pop the
390
+ # entry for this rule from the stack.
391
+ @val = @stack.last.val
392
+ res = nil
393
+ res = @stack.last.function.call unless @stack.last.function.nil?
394
+ @stack.pop
395
+
396
+ # If the rule is not repeatable we can store the result and break the
397
+ # outer loop to exit the function.
398
+ unless rule.repeatable
399
+ result = res
400
+ break
401
+ end
402
+
403
+ # Otherwise we append the result to the result array and turn repeat
404
+ # mode on.
405
+ result << res
406
+ repeatMode = true
407
+ end
408
+
409
+ Log.exit('parseRule', "Finished rule #{rule.name}")
410
+ return result
411
+ end
412
+
413
+ end
414
+
415
+ end
416
+
@@ -0,0 +1,263 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = TextParser/Pattern.rb -- The TaskJuggler III Project Management Software
5
+ #
6
+ # Copyright (c) 2006, 2007, 2008, 2009 by Chris Schlaeger <cs@kde.org>
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of version 2 of the GNU General Public License as
10
+ # published by the Free Software Foundation.
11
+ #
12
+
13
+ require 'TextParser/TokenDoc'
14
+
15
+ class TaskJuggler::TextParser
16
+
17
+ # This class models the most crutial elements of a syntax description - the
18
+ # pattern. A TextParserPattern primarily consists of a set of tokens. Tokens
19
+ # are Strings where the first character determines the type of the token.
20
+ # There are 4 known types.
21
+ #
22
+ # Terminal token: The terminal token is prefixed by an underscore. Terminal
23
+ # tokens are terminal symbols of the syntax tree. They just represent
24
+ # themselves.
25
+ #
26
+ # Variable token: The variable token describes values of a certain class such
27
+ # as strings or numbers. The token is prefixed by a dollar sign and the text
28
+ # of the token specifies the variable type. See ProjectFileParser for a
29
+ # complete list of variable types.
30
+ #
31
+ # Reference token: The reference token specifies a reference to another parser
32
+ # rule. The token is prefixed by a bang and the text matches the name of the
33
+ # rule. See TextParserRule for details.
34
+ #
35
+ # End token: The . token marks the expected end of the input stream.
36
+ #
37
+ # In addition to the pure syntax tree information the pattern also holds
38
+ # documentary information about the pattern.
39
+ class Pattern
40
+
41
+ attr_reader :keyword, :doc, :seeAlso, :exampleFile, :exampleTag,
42
+ :tokens, :function
43
+
44
+ def initialize(tokens, function = nil)
45
+ # A unique name for the pattern that is used in the documentation.
46
+ @keyword = nil
47
+ # Initialize pattern doc as empty.
48
+ @doc = nil
49
+ # A list of TokenDoc elements that describe the meaning of variable
50
+ # tokens. The order of the tokens and entries in the Array must correlate.
51
+ @args = []
52
+ # A list of references to other patterns that are related to this pattern.
53
+ @seeAlso = []
54
+ # A reference to a file under test/TestSuite/Syntax/Correct and a tag
55
+ # within that file. This identifies example TJP code to be included with
56
+ # the reference manual.
57
+ @exampleFile = nil
58
+ @exampleTag = nil
59
+
60
+ tokens.each do |token|
61
+ unless '!$_.'.include?(token[0])
62
+ raise "Fatal Error: All pattern tokens must start with a type " +
63
+ "identifier [!$_.]: #{tokens.join(', ')}"
64
+ end
65
+ # Initialize pattern argument descriptions as empty.
66
+ @args << nil
67
+ end
68
+ @tokens = tokens
69
+ @function = function
70
+ # In some cases we don't want to show all tokens in the syntax
71
+ # documentation. This value specifies the index of the last shown token.
72
+ @lastSyntaxToken = @tokens.length - 1
73
+ end
74
+
75
+ # Set the keyword and documentation text for the pattern.
76
+ def setDoc(keyword, doc)
77
+ @keyword = keyword
78
+ @doc = doc
79
+ end
80
+
81
+ # Set the documentation text and for the idx-th variable.
82
+ def setArg(idx, doc)
83
+ @args[idx] = doc
84
+ end
85
+
86
+ # Restrict the syntax documentation to the first +idx+ tokens.
87
+ def setLastSyntaxToken(idx)
88
+ @lastSyntaxToken = idx
89
+ end
90
+
91
+ # Set the references to related patterns.
92
+ def setSeeAlso(also)
93
+ @seeAlso = also
94
+ end
95
+
96
+ # Set the file and tag for the TJP code example.
97
+ def setExample(file, tag)
98
+ @exampleFile = file
99
+ @exampleTag = tag
100
+ end
101
+
102
+ # Conveniance function to access individual tokens by index.
103
+ def [](i)
104
+ @tokens[i]
105
+ end
106
+
107
+ # Iterator for tokens.
108
+ def each
109
+ @tokens.each { |tok| yield tok }
110
+ end
111
+
112
+ # Returns true of the pattern is empty.
113
+ def empty?
114
+ @tokens.empty?
115
+ end
116
+
117
+ # Returns the number of tokens in the pattern.
118
+ def length
119
+ @tokens.length
120
+ end
121
+
122
+ # Return true if all tokens of the pattern are optional. If a token
123
+ # references a rule, this rule is followed for the check.
124
+ def optional?(rules)
125
+ @tokens.each do |token|
126
+ if token[0] == ?_ || token[0] == ?$
127
+ return false
128
+ elsif token[0] == ?!
129
+ token = token[1..-1]
130
+ if !rules[token].optional?(rules)
131
+ return false
132
+ end
133
+ end
134
+ end
135
+ true
136
+ end
137
+
138
+ # Returns true if the i-th token is a terminal symbol.
139
+ def terminalSymbol?(i)
140
+ @tokens[i][0] == ?$ || @tokens[i][0] == ?_
141
+ end
142
+
143
+ # Find recursively the first terminal token of this pattern. If an index is
144
+ # specified start the search at this n-th pattern token instead of the
145
+ # first. The return value is either nil or a [ token, pattern ] tuple.
146
+ def terminalToken(rules, index = 0)
147
+ # Terminal token start with an underscore or dollar character.
148
+ if @tokens[index][0] == ?_ || @tokens[index][0] == ?$
149
+ return [ @tokens[index].slice(1, @tokens[index].length - 1), self ]
150
+ elsif @tokens[index][0] == ?!
151
+ # Token starting with a bang reference another rule. We have to continue
152
+ # the search at this rule. First, we get rid of the bang to get the rule
153
+ # name.
154
+ token = @tokens[index].slice(1, @tokens[index].length - 1)
155
+ # Then find the rule
156
+ rule = rules[token]
157
+ # The rule may only have a single pattern. If not, then this pattern has
158
+ # no terminal token.
159
+ return nil if rule.patterns.length != 1
160
+ return rule.patterns[0].terminalToken(rules)
161
+ end
162
+ nil
163
+ end
164
+
165
+ # Returns a string that expresses the elements of the pattern in an EBNF
166
+ # like fashion. The resolution of the pattern is done recursively. This is
167
+ # just the wrapper function that sets up the stack.
168
+ def to_syntax(argDocs, rules, skip = 0)
169
+ to_syntax_r({}, argDocs, rules, skip)
170
+ end
171
+
172
+ def to_syntax_r(stack, argDocs, rules, skip)
173
+ # If we find ourself on the stack we hit a recursive pattern. This is used
174
+ # in repetitions.
175
+ if stack[self]
176
+ return '[, ... ]'
177
+ end
178
+
179
+ # "Push" us on the stack.
180
+ stack[self] = true
181
+
182
+ str = ''
183
+ first = true
184
+ # Analyze the tokens of the pattern skipping the first 'skip' tokens.
185
+ skip.upto(@lastSyntaxToken) do |i|
186
+ token = @tokens[i]
187
+ # If the first token is a _{ the pattern describes optional attributes.
188
+ # They are represented by a standard idiom.
189
+ if first
190
+ first = false
191
+ return '{ <attributes> }' if token == '_{'
192
+ else
193
+ # Separate the syntax elemens by a whitespace.
194
+ str << ' '
195
+ end
196
+
197
+ typeId = token[0]
198
+ token = token.slice(1, token.length - 1)
199
+
200
+ if @args[i]
201
+ # The argument is documented in the syntax definition. We copy the
202
+ # entry as we need to modify it.
203
+ argDoc = @args[i].clone
204
+
205
+ # A documented argument without a name is a terminal token. We use the
206
+ # terminal symbol as name.
207
+ if @args[i].name.nil?
208
+ str << "#{token}"
209
+ argDoc.name = token
210
+ else
211
+ str << "<#{@args[i].name}>"
212
+ end
213
+ addArgDoc(argDocs, argDoc)
214
+
215
+ # Documented arguments don't have the type set yet. Use the token
216
+ # value for that.
217
+ if typeId == ?$
218
+ argDoc.typeSpec = "<#{token}>"
219
+ end
220
+ else
221
+ # Undocumented tokens are recursively expanded.
222
+ case typeId
223
+ when ?_
224
+ # Literals are shown as such.
225
+ str << token
226
+ when ?$
227
+ # Variables are enclosed by angle brackets.
228
+ str << '<' + token + '>'
229
+ when ?!
230
+ if rules[token].patterns.length == 1 &&
231
+ !rules[token].patterns[0].doc.nil?
232
+ addArgDoc(argDocs, TokenDoc.new(rules[token].patterns[0].keyword,
233
+ rules[token].patterns[0]))
234
+ str << '<' + rules[token].patterns[0].keyword + '>'
235
+ else
236
+ # References are followed recursively.
237
+ str << rules[token].to_syntax(stack, argDocs, rules, 0)
238
+ end
239
+ end
240
+ end
241
+ end
242
+ # Remove us from the "stack" again.
243
+ stack.delete(self)
244
+ str
245
+ end
246
+
247
+ def to_s
248
+ @tokens.join(' ')
249
+ end
250
+
251
+ private
252
+
253
+ def addArgDoc(argDocs, argDoc)
254
+ raise 'Error' if argDoc.name.nil?
255
+ argDocs.each do |ad|
256
+ return if ad.name == argDoc.name
257
+ end
258
+ argDocs << argDoc
259
+ end
260
+
261
+ end
262
+
263
+ end