guard-mthaml 0.1.0

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 (341) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +34 -0
  3. data/lib/guard/mthaml.rb +140 -0
  4. data/lib/guard/mthaml/compiler/MtHaml.php +255 -0
  5. data/lib/guard/mthaml/templates/Guardfile +12 -0
  6. data/lib/guard/mthaml/version.rb +5 -0
  7. data/vendor/autoload.php +7 -0
  8. data/vendor/coffeescript/coffeescript/LICENSE +22 -0
  9. data/vendor/coffeescript/coffeescript/README.md +96 -0
  10. data/vendor/coffeescript/coffeescript/composer.json +23 -0
  11. data/vendor/coffeescript/coffeescript/grammar.y +309 -0
  12. data/vendor/coffeescript/coffeescript/make.php +115 -0
  13. data/vendor/coffeescript/coffeescript/src/CoffeeScript/Compiler.php +76 -0
  14. data/vendor/coffeescript/coffeescript/src/CoffeeScript/Error.php +15 -0
  15. data/vendor/coffeescript/coffeescript/src/CoffeeScript/Helpers.php +116 -0
  16. data/vendor/coffeescript/coffeescript/src/CoffeeScript/Init.php +96 -0
  17. data/vendor/coffeescript/coffeescript/src/CoffeeScript/Lexer.php +1356 -0
  18. data/vendor/coffeescript/coffeescript/src/CoffeeScript/Nodes.php +105 -0
  19. data/vendor/coffeescript/coffeescript/src/CoffeeScript/Parser.php +3326 -0
  20. data/vendor/coffeescript/coffeescript/src/CoffeeScript/Rewriter.php +552 -0
  21. data/vendor/coffeescript/coffeescript/src/CoffeeScript/Scope.php +196 -0
  22. data/vendor/coffeescript/coffeescript/src/CoffeeScript/SyntaxError.php +9 -0
  23. data/vendor/coffeescript/coffeescript/src/CoffeeScript/Value.php +20 -0
  24. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Access.php +31 -0
  25. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Arr.php +69 -0
  26. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Assign.php +353 -0
  27. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Base.php +288 -0
  28. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Block.php +294 -0
  29. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Call.php +283 -0
  30. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Class.php +282 -0
  31. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Closure.php +49 -0
  32. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Code.php +203 -0
  33. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Comment.php +39 -0
  34. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Existence.php +42 -0
  35. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Extends.php +26 -0
  36. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/For.php +250 -0
  37. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/If.php +161 -0
  38. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/In.php +99 -0
  39. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Index.php +27 -0
  40. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Literal.php +96 -0
  41. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Obj.php +126 -0
  42. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Op.php +292 -0
  43. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Param.php +119 -0
  44. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Parens.php +45 -0
  45. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Range.php +225 -0
  46. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Return.php +56 -0
  47. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Slice.php +47 -0
  48. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Splat.php +100 -0
  49. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Switch.php +121 -0
  50. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Throw.php +37 -0
  51. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Try.php +79 -0
  52. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Value.php +210 -0
  53. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/While.php +112 -0
  54. data/vendor/coffeescript/coffeescript/tests/cases/arrays.coffee +77 -0
  55. data/vendor/coffeescript/coffeescript/tests/cases/assignment.coffee +352 -0
  56. data/vendor/coffeescript/coffeescript/tests/cases/booleans.coffee +21 -0
  57. data/vendor/coffeescript/coffeescript/tests/cases/classes.coffee +681 -0
  58. data/vendor/coffeescript/coffeescript/tests/cases/comments.coffee +207 -0
  59. data/vendor/coffeescript/coffeescript/tests/cases/compilation.coffee +72 -0
  60. data/vendor/coffeescript/coffeescript/tests/cases/comprehensions.coffee +501 -0
  61. data/vendor/coffeescript/coffeescript/tests/cases/control_flow.coffee +430 -0
  62. data/vendor/coffeescript/coffeescript/tests/cases/eval.coffee +29 -0
  63. data/vendor/coffeescript/coffeescript/tests/cases/exception_handling.coffee +102 -0
  64. data/vendor/coffeescript/coffeescript/tests/cases/formatting.coffee +146 -0
  65. data/vendor/coffeescript/coffeescript/tests/cases/function_invocation.coffee +552 -0
  66. data/vendor/coffeescript/coffeescript/tests/cases/functions.coffee +188 -0
  67. data/vendor/coffeescript/coffeescript/tests/cases/helpers.coffee +96 -0
  68. data/vendor/coffeescript/coffeescript/tests/cases/importing.coffee +18 -0
  69. data/vendor/coffeescript/coffeescript/tests/cases/interpolation.coffee +138 -0
  70. data/vendor/coffeescript/coffeescript/tests/cases/javascript_literals.coffee +10 -0
  71. data/vendor/coffeescript/coffeescript/tests/cases/numbers.coffee +76 -0
  72. data/vendor/coffeescript/coffeescript/tests/cases/objects.coffee +271 -0
  73. data/vendor/coffeescript/coffeescript/tests/cases/operators.coffee +277 -0
  74. data/vendor/coffeescript/coffeescript/tests/cases/option_parser.coffee +43 -0
  75. data/vendor/coffeescript/coffeescript/tests/cases/ranges.coffee +88 -0
  76. data/vendor/coffeescript/coffeescript/tests/cases/regexps.coffee +63 -0
  77. data/vendor/coffeescript/coffeescript/tests/cases/scope.coffee +43 -0
  78. data/vendor/coffeescript/coffeescript/tests/cases/slicing_and_splicing.coffee +143 -0
  79. data/vendor/coffeescript/coffeescript/tests/cases/soaks.coffee +134 -0
  80. data/vendor/coffeescript/coffeescript/tests/cases/strict.coffee +155 -0
  81. data/vendor/coffeescript/coffeescript/tests/cases/strings.coffee +107 -0
  82. data/vendor/coffeescript/coffeescript/tests/css/style.css +43 -0
  83. data/vendor/coffeescript/coffeescript/tests/index.php +119 -0
  84. data/vendor/coffeescript/coffeescript/tests/js/lib/coffeescript_1.1.1.js +8 -0
  85. data/vendor/coffeescript/coffeescript/tests/js/lib/coffeescript_1.2.0.js +8 -0
  86. data/vendor/coffeescript/coffeescript/tests/js/lib/coffeescript_1.3.0.js +8 -0
  87. data/vendor/coffeescript/coffeescript/tests/js/lib/coffeescript_1.3.1.js +8 -0
  88. data/vendor/coffeescript/coffeescript/tests/js/lib/diff.js +276 -0
  89. data/vendor/coffeescript/coffeescript/tests/js/main.js +123 -0
  90. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/LICENSE.txt +10 -0
  91. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/Lempar.php +948 -0
  92. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/Action.php +257 -0
  93. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/ActionTable.php +299 -0
  94. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/Config.php +574 -0
  95. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/Data.php +1857 -0
  96. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/Parser.php +851 -0
  97. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/PropagationLink.php +126 -0
  98. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/Rule.php +144 -0
  99. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/State.php +283 -0
  100. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/Symbol.php +288 -0
  101. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/cli.php +5 -0
  102. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/ParserGenerator.php +811 -0
  103. data/vendor/composer/ClassLoader.php +383 -0
  104. data/vendor/composer/autoload_classmap.php +9 -0
  105. data/vendor/composer/autoload_namespaces.php +12 -0
  106. data/vendor/composer/autoload_psr4.php +10 -0
  107. data/vendor/composer/autoload_real.php +50 -0
  108. data/vendor/composer/installed.json +166 -0
  109. data/vendor/michelf/php-markdown/License.md +36 -0
  110. data/vendor/michelf/php-markdown/Michelf/Markdown.inc.php +10 -0
  111. data/vendor/michelf/php-markdown/Michelf/Markdown.php +3117 -0
  112. data/vendor/michelf/php-markdown/Michelf/MarkdownExtra.inc.php +11 -0
  113. data/vendor/michelf/php-markdown/Michelf/MarkdownExtra.php +38 -0
  114. data/vendor/michelf/php-markdown/Michelf/MarkdownInterface.inc.php +9 -0
  115. data/vendor/michelf/php-markdown/Michelf/MarkdownInterface.php +37 -0
  116. data/vendor/michelf/php-markdown/Readme.md +305 -0
  117. data/vendor/michelf/php-markdown/Readme.php +31 -0
  118. data/vendor/michelf/php-markdown/composer.json +31 -0
  119. data/vendor/mthaml/mthaml/CHANGELOG +48 -0
  120. data/vendor/mthaml/mthaml/LICENSE +44 -0
  121. data/vendor/mthaml/mthaml/README.markdown +262 -0
  122. data/vendor/mthaml/mthaml/composer.json +45 -0
  123. data/vendor/mthaml/mthaml/docs/Makefile +153 -0
  124. data/vendor/mthaml/mthaml/docs/_static/mthaml.css +30 -0
  125. data/vendor/mthaml/mthaml/docs/_theme/mthaml/theme.conf +4 -0
  126. data/vendor/mthaml/mthaml/docs/conf.py +242 -0
  127. data/vendor/mthaml/mthaml/docs/index.rst +18 -0
  128. data/vendor/mthaml/mthaml/docs/twig-syntax.rst +274 -0
  129. data/vendor/mthaml/mthaml/examples/README.md +5 -0
  130. data/vendor/mthaml/mthaml/examples/autoload.php +8 -0
  131. data/vendor/mthaml/mthaml/examples/example-php.haml +5 -0
  132. data/vendor/mthaml/mthaml/examples/example-php.php +37 -0
  133. data/vendor/mthaml/mthaml/examples/example-twig-noext.twig +11 -0
  134. data/vendor/mthaml/mthaml/examples/example-twig.haml +9 -0
  135. data/vendor/mthaml/mthaml/examples/example-twig.php +60 -0
  136. data/vendor/mthaml/mthaml/examples/example.twig.haml +8 -0
  137. data/vendor/mthaml/mthaml/lib/MtHaml/Autoloader.php +22 -0
  138. data/vendor/mthaml/mthaml/lib/MtHaml/Environment.php +178 -0
  139. data/vendor/mthaml/mthaml/lib/MtHaml/Escaping.php +33 -0
  140. data/vendor/mthaml/mthaml/lib/MtHaml/Exception.php +9 -0
  141. data/vendor/mthaml/mthaml/lib/MtHaml/Exception/SyntaxErrorException.php +9 -0
  142. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/AbstractFilter.php +43 -0
  143. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Cdata.php +16 -0
  144. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/CoffeeScript.php +33 -0
  145. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Css.php +26 -0
  146. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Escaped.php +22 -0
  147. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/FilterInterface.php +15 -0
  148. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Javascript.php +26 -0
  149. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Less.php +27 -0
  150. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Less/LeafoLess.php +20 -0
  151. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Less/OyejorgeLess.php +23 -0
  152. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Markdown.php +58 -0
  153. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Markdown/CebeMarkdown.php +22 -0
  154. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Markdown/Ciconia.php +21 -0
  155. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Markdown/MichelfMarkdown.php +21 -0
  156. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Markdown/Parsedown.php +21 -0
  157. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Php.php +37 -0
  158. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Plain.php +24 -0
  159. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Preserve.php +19 -0
  160. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Scss.php +37 -0
  161. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Twig.php +47 -0
  162. data/vendor/mthaml/mthaml/lib/MtHaml/Indentation/Indentation.php +96 -0
  163. data/vendor/mthaml/mthaml/lib/MtHaml/Indentation/IndentationException.php +9 -0
  164. data/vendor/mthaml/mthaml/lib/MtHaml/Indentation/IndentationInterface.php +50 -0
  165. data/vendor/mthaml/mthaml/lib/MtHaml/Indentation/Undefined.php +41 -0
  166. data/vendor/mthaml/mthaml/lib/MtHaml/Node/Comment.php +71 -0
  167. data/vendor/mthaml/mthaml/lib/MtHaml/Node/Doctype.php +96 -0
  168. data/vendor/mthaml/mthaml/lib/MtHaml/Node/EscapableAbstract.php +19 -0
  169. data/vendor/mthaml/mthaml/lib/MtHaml/Node/Filter.php +51 -0
  170. data/vendor/mthaml/mthaml/lib/MtHaml/Node/Insert.php +42 -0
  171. data/vendor/mthaml/mthaml/lib/MtHaml/Node/InterpolatedString.php +73 -0
  172. data/vendor/mthaml/mthaml/lib/MtHaml/Node/NestAbstract.php +117 -0
  173. data/vendor/mthaml/mthaml/lib/MtHaml/Node/NestInterface.php +10 -0
  174. data/vendor/mthaml/mthaml/lib/MtHaml/Node/NodeAbstract.php +77 -0
  175. data/vendor/mthaml/mthaml/lib/MtHaml/Node/ObjectRefClass.php +42 -0
  176. data/vendor/mthaml/mthaml/lib/MtHaml/Node/ObjectRefId.php +42 -0
  177. data/vendor/mthaml/mthaml/lib/MtHaml/Node/Root.php +35 -0
  178. data/vendor/mthaml/mthaml/lib/MtHaml/Node/Run.php +71 -0
  179. data/vendor/mthaml/mthaml/lib/MtHaml/Node/Statement.php +45 -0
  180. data/vendor/mthaml/mthaml/lib/MtHaml/Node/Tag.php +90 -0
  181. data/vendor/mthaml/mthaml/lib/MtHaml/Node/TagAttribute.php +62 -0
  182. data/vendor/mthaml/mthaml/lib/MtHaml/Node/TagAttributeInterpolation.php +24 -0
  183. data/vendor/mthaml/mthaml/lib/MtHaml/Node/TagAttributeList.php +24 -0
  184. data/vendor/mthaml/mthaml/lib/MtHaml/Node/Text.php +37 -0
  185. data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/Autoclose.php +25 -0
  186. data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/Escaping.php +105 -0
  187. data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/MergeAttrs.php +110 -0
  188. data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/Midblock.php +37 -0
  189. data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/NodeVisitorAbstract.php +226 -0
  190. data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/NodeVisitorInterface.php +97 -0
  191. data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/PhpRenderer.php +288 -0
  192. data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/Printer.php +265 -0
  193. data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/RendererAbstract.php +581 -0
  194. data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/TwigRenderer.php +252 -0
  195. data/vendor/mthaml/mthaml/lib/MtHaml/Parser.php +862 -0
  196. data/vendor/mthaml/mthaml/lib/MtHaml/Parser/Buffer.php +147 -0
  197. data/vendor/mthaml/mthaml/lib/MtHaml/Runtime.php +218 -0
  198. data/vendor/mthaml/mthaml/lib/MtHaml/Runtime/AttributeInterpolation.php +16 -0
  199. data/vendor/mthaml/mthaml/lib/MtHaml/Runtime/AttributeList.php +16 -0
  200. data/vendor/mthaml/mthaml/lib/MtHaml/Support/Php/Executor.php +157 -0
  201. data/vendor/mthaml/mthaml/lib/MtHaml/Support/Twig/Extension.php +47 -0
  202. data/vendor/mthaml/mthaml/lib/MtHaml/Support/Twig/Lexer.php +48 -0
  203. data/vendor/mthaml/mthaml/lib/MtHaml/Support/Twig/Loader.php +81 -0
  204. data/vendor/mthaml/mthaml/lib/MtHaml/Target/Php.php +23 -0
  205. data/vendor/mthaml/mthaml/lib/MtHaml/Target/TargetAbstract.php +87 -0
  206. data/vendor/mthaml/mthaml/lib/MtHaml/Target/TargetInterface.php +12 -0
  207. data/vendor/mthaml/mthaml/lib/MtHaml/Target/Twig.php +23 -0
  208. data/vendor/mthaml/mthaml/lib/MtHaml/TreeBuilder.php +100 -0
  209. data/vendor/mthaml/mthaml/lib/MtHaml/TreeBuilderException.php +9 -0
  210. data/vendor/mthaml/mthaml/phpunit.xml +25 -0
  211. data/vendor/mthaml/mthaml/test/MtHaml/Tests/EnvironmentTest.php +59 -0
  212. data/vendor/mthaml/mthaml/test/MtHaml/Tests/HamlSpecTest.php +83 -0
  213. data/vendor/mthaml/mthaml/test/MtHaml/Tests/IndentationTest.php +140 -0
  214. data/vendor/mthaml/mthaml/test/MtHaml/Tests/Node/DoctypeTest.php +51 -0
  215. data/vendor/mthaml/mthaml/test/MtHaml/Tests/Node/NodeTest.php +110 -0
  216. data/vendor/mthaml/mthaml/test/MtHaml/Tests/NodeVisitor/PhpRendererTest.php +113 -0
  217. data/vendor/mthaml/mthaml/test/MtHaml/Tests/NodeVisitor/TwigRendererTest.php +68 -0
  218. data/vendor/mthaml/mthaml/test/MtHaml/Tests/NodeVisitorsTest.php +44 -0
  219. data/vendor/mthaml/mthaml/test/MtHaml/Tests/Parser/BufferTest.php +77 -0
  220. data/vendor/mthaml/mthaml/test/MtHaml/Tests/ParserTest.php +47 -0
  221. data/vendor/mthaml/mthaml/test/MtHaml/Tests/RuntimeTest.php +356 -0
  222. data/vendor/mthaml/mthaml/test/MtHaml/Tests/Support/Php/ExecutorTest.php +83 -0
  223. data/vendor/mthaml/mthaml/test/MtHaml/Tests/Support/Twig/LoaderTest.php +65 -0
  224. data/vendor/mthaml/mthaml/test/MtHaml/Tests/TestCase.php +49 -0
  225. data/vendor/mthaml/mthaml/test/MtHaml/Tests/TestCaseTest.php +50 -0
  226. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/Support/Php/Executor.001.haml +1 -0
  227. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/attr_list_php.test +20 -0
  228. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/attr_list_twig.test +12 -0
  229. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/boolean_attr_php.test +16 -0
  230. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/boolean_attr_twig.test +16 -0
  231. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/bug28_php.test +15 -0
  232. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/bug28_twig.test +15 -0
  233. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/bug42.test +13 -0
  234. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/bug8_twig.test +10 -0
  235. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/coffeescript_filter.test +31 -0
  236. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/comments.test +26 -0
  237. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/cond_cmt.test +25 -0
  238. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/doctype.test +18 -0
  239. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/doctype_html4.test +20 -0
  240. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/doctype_invalid.test +12 -0
  241. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/doctype_invalid_xhtml.test +12 -0
  242. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/doctype_php.test +18 -0
  243. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/doctype_xhtml.test +30 -0
  244. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/filters.test +51 -0
  245. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/insert_non_echo_php.test +11 -0
  246. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/insert_non_echo_twig.test +11 -0
  247. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/interpolation_in_html_attrs_php.test +31 -0
  248. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/interpolation_in_html_attrs_twig.test +31 -0
  249. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/less_filter_leafo.test +33 -0
  250. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/less_filter_oyejorge.test +49 -0
  251. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/markdown_filter_cebemarkdown.test +35 -0
  252. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/markdown_filter_ciconia.test +36 -0
  253. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/markdown_filter_michelf.test +34 -0
  254. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/markdown_filter_parsedown.test +31 -0
  255. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/markdown_optimization_filter_michelf.test +23 -0
  256. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/mergeattrs.test +18 -0
  257. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/nuke_inner_whitespace.test +77 -0
  258. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/nuke_outer_whitespace.test +122 -0
  259. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/object_ref_php.test +14 -0
  260. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/object_ref_twig.test +14 -0
  261. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/php.test +109 -0
  262. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/php_autoescaping.test +22 -0
  263. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/php_autoescaping_once.test +25 -0
  264. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/php_blocks.test +29 -0
  265. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/php_filters.test +42 -0
  266. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/scss_filter.test +32 -0
  267. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/strip_inline_comments_php.test +22 -0
  268. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/test.test +24 -0
  269. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/trailing_semicolon_php.test +14 -0
  270. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/try_catch_php.test +17 -0
  271. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/twig.test +112 -0
  272. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/twig_blocks.test +29 -0
  273. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/twig_filters.test +37 -0
  274. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/twig_whitespace.test +32 -0
  275. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/whitespace.test +63 -0
  276. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/nodevisitors/autoclose.test +30 -0
  277. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/nodevisitors/escaping.test +52 -0
  278. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/nodevisitors/escaping_attr_once.test +52 -0
  279. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/nodevisitors/escaping_html_false.test +52 -0
  280. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/nodevisitors/mergeattrs.test +26 -0
  281. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/nodevisitors/midblock.test +54 -0
  282. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/nodevisitors/midblock_002.test +32 -0
  283. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/attr_list.test +14 -0
  284. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/attrs.test +42 -0
  285. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/attrs_002.test +35 -0
  286. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/attrs_003.test +30 -0
  287. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/attrs_html_linebreak.test +17 -0
  288. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/blocks.test +27 -0
  289. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/blocks_002.test +15 -0
  290. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/boolean_attr.test +19 -0
  291. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/bug28.test +15 -0
  292. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/bug8.test +11 -0
  293. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/cond_cmt.test +23 -0
  294. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/doctype.test +11 -0
  295. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/double_equal.test +7 -0
  296. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/empty_line_after_multiline.test +10 -0
  297. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_001.test +8 -0
  298. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_002.test +8 -0
  299. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_003.test +8 -0
  300. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_004.test +6 -0
  301. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_005.test +5 -0
  302. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_006.test +7 -0
  303. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_007.test +7 -0
  304. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_008.test +7 -0
  305. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_009.test +5 -0
  306. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_010.test +5 -0
  307. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_013.test +5 -0
  308. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_016.test +7 -0
  309. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_017.test +8 -0
  310. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_018.test +6 -0
  311. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_019.test +6 -0
  312. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_020.test +5 -0
  313. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/filters.test +20 -0
  314. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/filters_002.test +19 -0
  315. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/filters_003.test +13 -0
  316. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/filters_004.test +21 -0
  317. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/filters_005.test +22 -0
  318. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/filters_006.test +23 -0
  319. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/insertflags.test +17 -0
  320. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/interpolation.test +36 -0
  321. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/interpolation_in_html_attrs.test +17 -0
  322. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/multiline.test +18 -0
  323. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/multiline_code.test +59 -0
  324. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/multiple_attr_kinds.test +47 -0
  325. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/non_rendered_comment.test +31 -0
  326. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/ns.test +11 -0
  327. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/object_ref.test +22 -0
  328. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/object_ref_error1.test +5 -0
  329. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/object_ref_error2.test +5 -0
  330. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/quotes_in_haml.test +10 -0
  331. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/ruby19_attrs.test +11 -0
  332. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/ruby_attrs_comma.test +23 -0
  333. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/ruby_attrs_comma_errors_001.test +5 -0
  334. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/ruby_attrs_comma_errors_002.test +5 -0
  335. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/ruby_attrs_comma_errors_003.test +5 -0
  336. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/standard.test +114 -0
  337. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/tagflags.test +39 -0
  338. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/runtime/php_filters.test +28 -0
  339. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/runtime/twig_filters.test +31 -0
  340. data/vendor/mthaml/mthaml/test/bootstrap.php +3 -0
  341. metadata +398 -0
@@ -0,0 +1,1857 @@
1
+ <?php
2
+ /**
3
+ * PHP_ParserGenerator, a php 5 parser generator.
4
+ *
5
+ * This is a direct port of the Lemon parser generator, found at
6
+ * {@link http://www.hwaci.com/sw/lemon/}
7
+ *
8
+ * PHP version 5
9
+ *
10
+ * LICENSE:
11
+ *
12
+ * Copyright (c) 2006, Gregory Beaver <cellog@php.net>
13
+ * All rights reserved.
14
+ *
15
+ * Redistribution and use in source and binary forms, with or without
16
+ * modification, are permitted provided that the following conditions
17
+ * are met:
18
+ *
19
+ * * Redistributions of source code must retain the above copyright
20
+ * notice, this list of conditions and the following disclaimer.
21
+ * * Redistributions in binary form must reproduce the above copyright
22
+ * notice, this list of conditions and the following disclaimer in
23
+ * the documentation and/or other materials provided with the distribution.
24
+ * * Neither the name of the PHP_ParserGenerator nor the names of its
25
+ * contributors may be used to endorse or promote products derived
26
+ * from this software without specific prior written permission.
27
+ *
28
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
29
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
30
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
32
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
33
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
34
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
35
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
36
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
37
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
38
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39
+ *
40
+ * @category php
41
+ * @package PHP_ParserGenerator
42
+ * @author Gregory Beaver <cellog@php.net>
43
+ * @copyright 2006 Gregory Beaver
44
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
45
+ * @version CVS: $Id: Data.php 302209 2010-08-14 14:32:56Z jespino $
46
+ * @since File available since Release 0.1.0
47
+ */
48
+ /**
49
+ /**
50
+ * The state vector for the entire parser generator is recorded in
51
+ * this class.
52
+ *
53
+ * @package PHP_ParserGenerator
54
+ * @author Gregory Beaver <cellog@php.net>
55
+ * @copyright 2006 Gregory Beaver
56
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
57
+ * @version @package_version@
58
+ * @since Class available since Release 0.1.0
59
+ */
60
+
61
+ class PHP_ParserGenerator_Data
62
+ {
63
+ /**
64
+ * Used for terminal and non-terminal offsets into the action table
65
+ * when their default should be used instead
66
+ */
67
+ const NO_OFFSET = -2147483647;
68
+ /**
69
+ * Table of states sorted by state number
70
+ * @var array array of {@link PHP_ParserGenerator_State} objects
71
+ */
72
+ public $sorted;
73
+ /**
74
+ * List of all rules
75
+ * @var PHP_ParserGenerator_Rule
76
+ */
77
+ public $rule;
78
+ /**
79
+ * Number of states
80
+ * @var int
81
+ */
82
+ public $nstate;
83
+ /**
84
+ * Number of rules
85
+ * @var int
86
+ */
87
+ public $nrule;
88
+ /**
89
+ * Number of terminal and nonterminal symbols
90
+ * @var int
91
+ */
92
+ public $nsymbol;
93
+ /**
94
+ * Number of terminal symbols (tokens)
95
+ * @var int
96
+ */
97
+ public $nterminal;
98
+ /**
99
+ * Sorted array of pointers to symbols
100
+ * @var array array of {@link PHP_ParserGenerator_Symbol} objects
101
+ */
102
+ public $symbols = array();
103
+ /**
104
+ * Number of errors
105
+ * @var int
106
+ */
107
+ public $errorcnt;
108
+ /**
109
+ * The error symbol
110
+ * @var PHP_ParserGenerator_Symbol
111
+ */
112
+ public $errsym;
113
+ /**
114
+ * Name of the generated parser
115
+ * @var string
116
+ */
117
+ public $name;
118
+ /**
119
+ * Unused relic from the C version
120
+ *
121
+ * Type of terminal symbols in the parser stack
122
+ * @var string
123
+ */
124
+ public $tokentype;
125
+ /**
126
+ * Unused relic from the C version
127
+ *
128
+ * The default type of non-terminal symbols
129
+ * @var string
130
+ */
131
+ public $vartype;
132
+ /**
133
+ * Name of the start symbol for the grammar
134
+ * @var string
135
+ */
136
+ public $start;
137
+ /**
138
+ * Size of the parser stack
139
+ *
140
+ * This is 100 by default, but is set with the %stack_size directive
141
+ * @var int
142
+ */
143
+ public $stacksize;
144
+ /**
145
+ * Code to put at the start of the parser file
146
+ *
147
+ * This is set by the %include directive
148
+ * @var string
149
+ */
150
+ public $include_code;
151
+ /**
152
+ * Line number for start of include code
153
+ * @var int
154
+ */
155
+ public $includeln;
156
+ /**
157
+ * Code to put in the parser class
158
+ *
159
+ * This is set by the %include_class directive
160
+ * @var string
161
+ */
162
+ public $include_classcode;
163
+ /**
164
+ * Line number for start of include code
165
+ * @var int
166
+ */
167
+ public $include_classln;
168
+ /**
169
+ * any extends/implements code
170
+ *
171
+ * This is set by the %declare_class directive
172
+ * @var string
173
+ */
174
+ /**
175
+ * Line number for class declaration code
176
+ * @var int
177
+ */
178
+ public $declare_classcode;
179
+ /**
180
+ * Line number for start of class declaration code
181
+ * @var int
182
+ */
183
+ public $declare_classln;
184
+ /**
185
+ * Code to execute when a syntax error is seen
186
+ *
187
+ * This is set by the %syntax_error directive
188
+ * @var string
189
+ */
190
+ public $error;
191
+ /**
192
+ * Line number for start of error code
193
+ * @var int
194
+ */
195
+ public $errorln;
196
+ /**
197
+ * Code to execute on a stack overflow
198
+ *
199
+ * This is set by the %stack_overflow directive
200
+ */
201
+ public $overflow;
202
+ /**
203
+ * Line number for start of overflow code
204
+ * @var int
205
+ */
206
+ public $overflowln;
207
+ /**
208
+ * Code to execute on parser failure
209
+ *
210
+ * This is set by the %parse_failure directive
211
+ * @var string
212
+ */
213
+ public $failure;
214
+ /**
215
+ * Line number for start of failure code
216
+ * @var int
217
+ */
218
+ public $failureln;
219
+ /**
220
+ * Code to execute when the parser acccepts (completes parsing)
221
+ *
222
+ * This is set by the %parse_accept directive
223
+ * @var string
224
+ */
225
+ public $accept;
226
+ /**
227
+ * Line number for the start of accept code
228
+ * @var int
229
+ */
230
+ public $acceptln;
231
+ /**
232
+ * Code appended to the generated file
233
+ *
234
+ * This is set by the %code directive
235
+ * @var string
236
+ */
237
+ public $extracode;
238
+ /**
239
+ * Line number for the start of the extra code
240
+ * @var int
241
+ */
242
+ public $extracodeln;
243
+ /**
244
+ * Code to execute to destroy token data
245
+ *
246
+ * This is set by the %token_destructor directive
247
+ * @var string
248
+ */
249
+ public $tokendest;
250
+ /**
251
+ * Line number for token destroyer code
252
+ * @var int
253
+ */
254
+ public $tokendestln;
255
+ /**
256
+ * Code for the default non-terminal destructor
257
+ *
258
+ * This is set by the %default_destructor directive
259
+ * @var string
260
+ */
261
+ public $vardest;
262
+ /**
263
+ * Line number for default non-terminal destructor code
264
+ * @var int
265
+ */
266
+ public $vardestln;
267
+ /**
268
+ * Name of the input file
269
+ * @var string
270
+ */
271
+ public $filename;
272
+ /**
273
+ * Name of the input file without its extension
274
+ * @var string
275
+ */
276
+ public $filenosuffix;
277
+ /**
278
+ * Name of the current output file
279
+ * @var string
280
+ */
281
+ public $outname;
282
+ /**
283
+ * A prefix added to token names
284
+ * @var string
285
+ */
286
+ public $tokenprefix;
287
+ /**
288
+ * Number of parsing conflicts
289
+ * @var int
290
+ */
291
+ public $nconflict;
292
+ /**
293
+ * Size of the parse tables
294
+ * @var int
295
+ */
296
+ public $tablesize;
297
+ /**
298
+ * Public only basis configurations
299
+ */
300
+ public $basisflag;
301
+ /**
302
+ * True if any %fallback is seen in the grammer
303
+ * @var boolean
304
+ */
305
+ public $has_fallback;
306
+ /**
307
+ * Name of the program
308
+ * @var string
309
+ */
310
+ public $argv0;
311
+
312
+ /**
313
+ * Alternate parser template file
314
+ * @var string
315
+ */
316
+ public $parser_template = "";
317
+
318
+ /* Find a precedence symbol of every rule in the grammar.
319
+ *
320
+ * Those rules which have a precedence symbol coded in the input
321
+ * grammar using the "[symbol]" construct will already have the
322
+ * $rp->precsym field filled. Other rules take as their precedence
323
+ * symbol the first RHS symbol with a defined precedence. If there
324
+ * are not RHS symbols with a defined precedence, the precedence
325
+ * symbol field is left blank.
326
+ */
327
+ function FindRulePrecedences()
328
+ {
329
+ for ($rp = $this->rule; $rp; $rp = $rp->next) {
330
+ if ($rp->precsym === 0) {
331
+ for ($i = 0; $i < $rp->nrhs && $rp->precsym === 0; $i++) {
332
+ $sp = $rp->rhs[$i];
333
+ if ($sp->type == PHP_ParserGenerator_Symbol::MULTITERMINAL) {
334
+ for ($j = 0; $j < $sp->nsubsym; $j++) {
335
+ if ($sp->subsym[$j]->prec >= 0) {
336
+ $rp->precsym = $sp->subsym[$j];
337
+ break;
338
+ }
339
+ }
340
+ } elseif ($sp->prec >= 0) {
341
+ $rp->precsym = $rp->rhs[$i];
342
+ }
343
+ }
344
+ }
345
+ }
346
+ }
347
+
348
+ /**
349
+ * Find all nonterminals which will generate the empty string.
350
+ * Then go back and compute the first sets of every nonterminal.
351
+ * The first set is the set of all terminal symbols which can begin
352
+ * a string generated by that nonterminal.
353
+ */
354
+ function FindFirstSets()
355
+ {
356
+ for ($i = 0; $i < $this->nsymbol; $i++) {
357
+ $this->symbols[$i]->lambda = false;
358
+ }
359
+ for($i = $this->nterminal; $i < $this->nsymbol; $i++) {
360
+ $this->symbols[$i]->firstset = array();
361
+ }
362
+
363
+ /* First compute all lambdas */
364
+ do{
365
+ $progress = 0;
366
+ for ($rp = $this->rule; $rp; $rp = $rp->next) {
367
+ if ($rp->lhs->lambda) {
368
+ continue;
369
+ }
370
+ for ($i = 0; $i < $rp->nrhs; $i++) {
371
+ $sp = $rp->rhs[$i];
372
+ if ($sp->type != PHP_ParserGenerator_Symbol::TERMINAL || $sp->lambda === false) {
373
+ break;
374
+ }
375
+ }
376
+ if ($i === $rp->nrhs) {
377
+ $rp->lhs->lambda = true;
378
+ $progress = 1;
379
+ }
380
+ }
381
+ } while ($progress);
382
+
383
+ /* Now compute all first sets */
384
+ do {
385
+ $progress = 0;
386
+ for ($rp = $this->rule; $rp; $rp = $rp->next) {
387
+ $s1 = $rp->lhs;
388
+ for ($i = 0; $i < $rp->nrhs; $i++) {
389
+ $s2 = $rp->rhs[$i];
390
+ if ($s2->type == PHP_ParserGenerator_Symbol::TERMINAL) {
391
+ //progress += SetAdd(s1->firstset,s2->index);
392
+ $progress += isset($s1->firstset[$s2->index]) ? 0 : 1;
393
+ $s1->firstset[$s2->index] = 1;
394
+ break;
395
+ } elseif ($s2->type == PHP_ParserGenerator_Symbol::MULTITERMINAL) {
396
+ for ($j = 0; $j < $s2->nsubsym; $j++) {
397
+ //progress += SetAdd(s1->firstset,s2->subsym[j]->index);
398
+ $progress += isset($s1->firstset[$s2->subsym[$j]->index]) ? 0 : 1;
399
+ $s1->firstset[$s2->subsym[$j]->index] = 1;
400
+ }
401
+ break;
402
+ } elseif ($s1 === $s2) {
403
+ if ($s1->lambda === false) {
404
+ break;
405
+ }
406
+ } else {
407
+ //progress += SetUnion(s1->firstset,s2->firstset);
408
+ $test = array_diff_key($s2->firstset, $s1->firstset);
409
+ if (count($test)) {
410
+ $progress++;
411
+ $s1->firstset += $test;
412
+ }
413
+ if ($s2->lambda === false) {
414
+ break;
415
+ }
416
+ }
417
+ }
418
+ }
419
+ } while ($progress);
420
+ }
421
+
422
+ /**
423
+ * Compute all LR(0) states for the grammar. Links
424
+ * are added to between some states so that the LR(1) follow sets
425
+ * can be computed later.
426
+ */
427
+ function FindStates()
428
+ {
429
+ PHP_ParserGenerator_Config::Configlist_init();
430
+
431
+ /* Find the start symbol */
432
+ if ($this->start) {
433
+ $sp = PHP_ParserGenerator_Symbol::Symbol_find($this->start);
434
+ if ($sp == false) {
435
+ PHP_ParserGenerator::ErrorMsg($this->filename, 0,
436
+ "The specified start symbol \"%s\" is not " .
437
+ "in a nonterminal of the grammar. \"%s\" will be used as the start " .
438
+ "symbol instead.", $this->start, $this->rule->lhs->name);
439
+ $this->errorcnt++;
440
+ $sp = $this->rule->lhs;
441
+ }
442
+ } else {
443
+ $sp = $this->rule->lhs;
444
+ }
445
+
446
+ /* Make sure the start symbol doesn't occur on the right-hand side of
447
+ ** any rule. Report an error if it does. (YACC would generate a new
448
+ ** start symbol in this case.) */
449
+ for ($rp = $this->rule; $rp; $rp = $rp->next) {
450
+ for ($i = 0; $i < $rp->nrhs; $i++) {
451
+ if ($rp->rhs[$i]->type == PHP_ParserGenerator_Symbol::MULTITERMINAL) {
452
+ foreach ($rp->rhs[$i]->subsym as $subsp) {
453
+ if ($subsp === $sp) {
454
+ PHP_ParserGenerator::ErrorMsg($this->filename, 0,
455
+ "The start symbol \"%s\" occurs on the " .
456
+ "right-hand side of a rule. This will result in a parser which " .
457
+ "does not work properly.", $sp->name);
458
+ $this->errorcnt++;
459
+ }
460
+ }
461
+ } elseif ($rp->rhs[$i] === $sp) {
462
+ PHP_ParserGenerator::ErrorMsg($this->filename, 0,
463
+ "The start symbol \"%s\" occurs on the " .
464
+ "right-hand side of a rule. This will result in a parser which " .
465
+ "does not work properly.", $sp->name);
466
+ $this->errorcnt++;
467
+ }
468
+ }
469
+ }
470
+
471
+ /* The basis configuration set for the first state
472
+ ** is all rules which have the start symbol as their
473
+ ** left-hand side */
474
+ for ($rp = $sp->rule; $rp; $rp = $rp->nextlhs) {
475
+ $newcfp = PHP_ParserGenerator_Config::Configlist_addbasis($rp, 0);
476
+ $newcfp->fws[0] = 1;
477
+ }
478
+
479
+ /* Compute the first state. All other states will be
480
+ ** computed automatically during the computation of the first one.
481
+ ** The returned pointer to the first state is not used. */
482
+ $newstp = array();
483
+ $newstp = $this->getstate();
484
+ if (is_array($newstp)) {
485
+ $this->buildshifts($newstp[0]); /* Recursively compute successor states */
486
+ }
487
+ }
488
+
489
+ /**
490
+ * @return PHP_ParserGenerator_State
491
+ */
492
+ private function getstate()
493
+ {
494
+ /* Extract the sorted basis of the new state. The basis was constructed
495
+ ** by prior calls to "Configlist_addbasis()". */
496
+ PHP_ParserGenerator_Config::Configlist_sortbasis();
497
+ $bp = PHP_ParserGenerator_Config::Configlist_basis();
498
+
499
+ /* Get a state with the same basis */
500
+ $stp = PHP_ParserGenerator_State::State_find($bp);
501
+ if ($stp) {
502
+ /* A state with the same basis already exists! Copy all the follow-set
503
+ ** propagation links from the state under construction into the
504
+ ** preexisting state, then return a pointer to the preexisting state */
505
+ for($x = $bp, $y = $stp->bp; $x && $y; $x = $x->bp, $y = $y->bp) {
506
+ PHP_ParserGenerator_PropagationLink::Plink_copy($y->bplp, $x->bplp);
507
+ PHP_ParserGenerator_PropagationLink::Plink_delete($x->fplp);
508
+ $x->fplp = $x->bplp = 0;
509
+ }
510
+ $cfp = PHP_ParserGenerator_Config::Configlist_return();
511
+ PHP_ParserGenerator_Config::Configlist_eat($cfp);
512
+ } else {
513
+ /* This really is a new state. Construct all the details */
514
+ PHP_ParserGenerator_Config::Configlist_closure($this); /* Compute the configuration closure */
515
+ PHP_ParserGenerator_Config::Configlist_sort(); /* Sort the configuration closure */
516
+ $cfp = PHP_ParserGenerator_Config::Configlist_return(); /* Get a pointer to the config list */
517
+ $stp = new PHP_ParserGenerator_State; /* A new state structure */
518
+ $stp->bp = $bp; /* Remember the configuration basis */
519
+ $stp->cfp = $cfp; /* Remember the configuration closure */
520
+ $stp->statenum = $this->nstate++; /* Every state gets a sequence number */
521
+ $stp->ap = 0; /* No actions, yet. */
522
+ PHP_ParserGenerator_State::State_insert($stp, $stp->bp); /* Add to the state table */
523
+ // this can't work, recursion is too deep, move it into FindStates()
524
+ //$this->buildshifts($stp); /* Recursively compute successor states */
525
+ return array($stp);
526
+ }
527
+ return $stp;
528
+ }
529
+
530
+ /**
531
+ * Construct all successor states to the given state. A "successor"
532
+ * state is any state which can be reached by a shift action.
533
+ * @param PHP_ParserGenerator_Data
534
+ * @param PHP_ParserGenerator_State The state from which successors are computed
535
+ */
536
+ private function buildshifts(PHP_ParserGenerator_State $stp)
537
+ {
538
+ // struct config *cfp; /* For looping thru the config closure of "stp" */
539
+ // struct config *bcfp; /* For the inner loop on config closure of "stp" */
540
+ // struct config *new; /* */
541
+ // struct symbol *sp; /* Symbol following the dot in configuration "cfp" */
542
+ // struct symbol *bsp; /* Symbol following the dot in configuration "bcfp" */
543
+ // struct state *newstp; /* A pointer to a successor state */
544
+
545
+ /* Each configuration becomes complete after it contibutes to a successor
546
+ ** state. Initially, all configurations are incomplete */
547
+ $cfp = $stp->cfp;
548
+ for ($cfp = $stp->cfp; $cfp; $cfp = $cfp->next) {
549
+ $cfp->status = PHP_ParserGenerator_Config::INCOMPLETE;
550
+ }
551
+
552
+ /* Loop through all configurations of the state "stp" */
553
+ for ($cfp = $stp->cfp; $cfp; $cfp = $cfp->next) {
554
+ if ($cfp->status == PHP_ParserGenerator_Config::COMPLETE) {
555
+ continue; /* Already used by inner loop */
556
+ }
557
+ if ($cfp->dot >= $cfp->rp->nrhs) {
558
+ continue; /* Can't shift this config */
559
+ }
560
+ PHP_ParserGenerator_Config::Configlist_reset(); /* Reset the new config set */
561
+ $sp = $cfp->rp->rhs[$cfp->dot]; /* Symbol after the dot */
562
+
563
+ /* For every configuration in the state "stp" which has the symbol "sp"
564
+ ** following its dot, add the same configuration to the basis set under
565
+ ** construction but with the dot shifted one symbol to the right. */
566
+ $bcfp = $cfp;
567
+ for ($bcfp = $cfp; $bcfp; $bcfp = $bcfp->next) {
568
+ if ($bcfp->status == PHP_ParserGenerator_Config::COMPLETE) {
569
+ continue; /* Already used */
570
+ }
571
+ if ($bcfp->dot >= $bcfp->rp->nrhs) {
572
+ continue; /* Can't shift this one */
573
+ }
574
+ $bsp = $bcfp->rp->rhs[$bcfp->dot]; /* Get symbol after dot */
575
+ if (!PHP_ParserGenerator_Symbol::same_symbol($bsp, $sp)) {
576
+ continue; /* Must be same as for "cfp" */
577
+ }
578
+ $bcfp->status = PHP_ParserGenerator_Config::COMPLETE; /* Mark this config as used */
579
+ $new = PHP_ParserGenerator_Config::Configlist_addbasis($bcfp->rp, $bcfp->dot + 1);
580
+ PHP_ParserGenerator_PropagationLink::Plink_add($new->bplp, $bcfp);
581
+ }
582
+
583
+ /* Get a pointer to the state described by the basis configuration set
584
+ ** constructed in the preceding loop */
585
+ $newstp = $this->getstate();
586
+ if (is_array($newstp)) {
587
+ $this->buildshifts($newstp[0]); /* Recursively compute successor states */
588
+ $newstp = $newstp[0];
589
+ }
590
+
591
+ /* The state "newstp" is reached from the state "stp" by a shift action
592
+ ** on the symbol "sp" */
593
+ if ($sp->type == PHP_ParserGenerator_Symbol::MULTITERMINAL) {
594
+ for($i = 0; $i < $sp->nsubsym; $i++) {
595
+ PHP_ParserGenerator_Action::Action_add($stp->ap, PHP_ParserGenerator_Action::SHIFT, $sp->subsym[$i],
596
+ $newstp);
597
+ }
598
+ } else {
599
+ PHP_ParserGenerator_Action::Action_add($stp->ap, PHP_ParserGenerator_Action::SHIFT, $sp, $newstp);
600
+ }
601
+ }
602
+ }
603
+
604
+ /**
605
+ * Construct the propagation links
606
+ */
607
+ function FindLinks()
608
+ {
609
+ /* Housekeeping detail:
610
+ ** Add to every propagate link a pointer back to the state to
611
+ ** which the link is attached. */
612
+ foreach ($this->sorted as $info) {
613
+ $info->key->stp = $info->data;
614
+ }
615
+
616
+ /* Convert all backlinks into forward links. Only the forward
617
+ ** links are used in the follow-set computation. */
618
+ for ($i = 0; $i < $this->nstate; $i++) {
619
+ $stp = $this->sorted[$i];
620
+ for ($cfp = $stp->data->cfp; $cfp; $cfp = $cfp->next) {
621
+ for ($plp = $cfp->bplp; $plp; $plp = $plp->next) {
622
+ $other = $plp->cfp;
623
+ PHP_ParserGenerator_PropagationLink::Plink_add($other->fplp, $cfp);
624
+ }
625
+ }
626
+ }
627
+ }
628
+
629
+ /**
630
+ * Compute the reduce actions, and resolve conflicts.
631
+ */
632
+ function FindActions()
633
+ {
634
+ /* Add all of the reduce actions
635
+ ** A reduce action is added for each element of the followset of
636
+ ** a configuration which has its dot at the extreme right.
637
+ */
638
+ for ($i = 0; $i < $this->nstate; $i++) { /* Loop over all states */
639
+ $stp = $this->sorted[$i]->data;
640
+ for ($cfp = $stp->cfp; $cfp; $cfp = $cfp->next) {
641
+ /* Loop over all configurations */
642
+ if ($cfp->rp->nrhs == $cfp->dot) { /* Is dot at extreme right? */
643
+ for ($j = 0; $j < $this->nterminal; $j++) {
644
+ if (isset($cfp->fws[$j])) {
645
+ /* Add a reduce action to the state "stp" which will reduce by the
646
+ ** rule "cfp->rp" if the lookahead symbol is "$this->symbols[j]" */
647
+ PHP_ParserGenerator_Action::Action_add($stp->ap, PHP_ParserGenerator_Action::REDUCE,
648
+ $this->symbols[$j], $cfp->rp);
649
+ }
650
+ }
651
+ }
652
+ }
653
+ }
654
+
655
+ /* Add the accepting token */
656
+ if ($this->start instanceof PHP_ParserGenerator_Symbol) {
657
+ $sp = PHP_ParserGenerator_Symbol::Symbol_find($this->start);
658
+ if ($sp === 0) {
659
+ $sp = $this->rule->lhs;
660
+ }
661
+ } else {
662
+ $sp = $this->rule->lhs;
663
+ }
664
+ /* Add to the first state (which is always the starting state of the
665
+ ** finite state machine) an action to ACCEPT if the lookahead is the
666
+ ** start nonterminal. */
667
+ PHP_ParserGenerator_Action::Action_add($this->sorted[0]->data->ap, PHP_ParserGenerator_Action::ACCEPT, $sp, 0);
668
+
669
+ /* Resolve conflicts */
670
+ for ($i = 0; $i < $this->nstate; $i++) {
671
+ // struct action *ap, *nap;
672
+ // struct state *stp;
673
+ $stp = $this->sorted[$i]->data;
674
+ if (!$stp->ap) {
675
+ throw new Exception('state has no actions associated');
676
+ }
677
+ echo 'processing state ' . $stp->statenum . " actions:\n";
678
+ for ($ap = $stp->ap; $ap !== 0 && $ap->next !== 0; $ap = $ap->next) {
679
+ echo ' Action ';
680
+ $ap->display(true);
681
+ }
682
+ $stp->ap = PHP_ParserGenerator_Action::Action_sort($stp->ap);
683
+ for ($ap = $stp->ap; $ap !== 0 && $ap->next !== 0; $ap = $ap->next) {
684
+ for ($nap = $ap->next; $nap !== 0 && $nap->sp === $ap->sp ; $nap = $nap->next) {
685
+ /* The two actions "ap" and "nap" have the same lookahead.
686
+ ** Figure out which one should be used */
687
+ $this->nconflict += $this->resolve_conflict($ap, $nap, $this->errsym);
688
+ }
689
+ }
690
+ }
691
+
692
+ /* Report an error for each rule that can never be reduced. */
693
+ for ($rp = $this->rule; $rp; $rp = $rp->next) {
694
+ $rp->canReduce = false;
695
+ }
696
+ for ($i = 0; $i < $this->nstate; $i++) {
697
+ for ($ap = $this->sorted[$i]->data->ap; $ap !== 0; $ap = $ap->next) {
698
+ if ($ap->type == PHP_ParserGenerator_Action::REDUCE) {
699
+ $ap->x->canReduce = true;
700
+ }
701
+ }
702
+ }
703
+ for ($rp = $this->rule; $rp !== 0; $rp = $rp->next) {
704
+ if ($rp->canReduce) {
705
+ continue;
706
+ }
707
+ PHP_ParserGenerator::ErrorMsg($this->filename, $rp->ruleline, "This rule can not be reduced (is not connected to the start symbol).\n");
708
+ $this->errorcnt++;
709
+ }
710
+ }
711
+
712
+ /** Resolve a conflict between the two given actions. If the
713
+ * conflict can't be resolve, return non-zero.
714
+ *
715
+ * NO LONGER TRUE:
716
+ * To resolve a conflict, first look to see if either action
717
+ * is on an error rule. In that case, take the action which
718
+ * is not associated with the error rule. If neither or both
719
+ * actions are associated with an error rule, then try to
720
+ * use precedence to resolve the conflict.
721
+ *
722
+ * If either action is a SHIFT, then it must be apx. This
723
+ * function won't work if apx->type==REDUCE and apy->type==SHIFT.
724
+ * @param PHP_ParserGenerator_Action
725
+ * @param PHP_ParserGenerator_Action
726
+ * @param PHP_ParserGenerator_Symbol|null The error symbol (if defined. NULL otherwise)
727
+ */
728
+ function resolve_conflict($apx, $apy, $errsym)
729
+ {
730
+ $errcnt = 0;
731
+ if ($apx->sp !== $apy->sp) {
732
+ throw new Exception('no conflict but resolve_conflict called');
733
+ }
734
+ if ($apx->type == PHP_ParserGenerator_Action::SHIFT && $apy->type == PHP_ParserGenerator_Action::REDUCE) {
735
+ $spx = $apx->sp;
736
+ $spy = $apy->x->precsym;
737
+ if ($spy === 0 || $spx->prec < 0 || $spy->prec < 0) {
738
+ /* Not enough precedence information. */
739
+ $apy->type = PHP_ParserGenerator_Action::CONFLICT;
740
+ $errcnt++;
741
+ } elseif ($spx->prec > $spy->prec) { /* Lower precedence wins */
742
+ $apy->type = PHP_ParserGenerator_Action::RD_RESOLVED;
743
+ } elseif ($spx->prec < $spy->prec) {
744
+ $apx->type = PHP_ParserGenerator_Action::SH_RESOLVED;
745
+ } elseif ($spx->prec === $spy->prec && $spx->assoc == PHP_ParserGenerator_Symbol::RIGHT) {
746
+ /* Use operator */
747
+ $apy->type = PHP_ParserGenerator_Action::RD_RESOLVED; /* associativity */
748
+ } elseif ($spx->prec === $spy->prec && $spx->assoc == PHP_ParserGenerator_Symbol::LEFT) {
749
+ /* to break tie */
750
+ $apx->type = PHP_ParserGenerator_Action::SH_RESOLVED;
751
+ } else {
752
+ if ($spx->prec !== $spy->prec || $spx->assoc !== PHP_ParserGenerator_Symbol::NONE) {
753
+ throw new Exception('$spx->prec !== $spy->prec || $spx->assoc !== PHP_ParserGenerator_Symbol::NONE');
754
+ }
755
+ $apy->type = PHP_ParserGenerator_Action::CONFLICT;
756
+ $errcnt++;
757
+ }
758
+ } elseif ($apx->type == PHP_ParserGenerator_Action::REDUCE && $apy->type == PHP_ParserGenerator_Action::REDUCE) {
759
+ $spx = $apx->x->precsym;
760
+ $spy = $apy->x->precsym;
761
+ if ($spx === 0 || $spy === 0 || $spx->prec < 0 ||
762
+ $spy->prec < 0 || $spx->prec === $spy->prec) {
763
+ $apy->type = PHP_ParserGenerator_Action::CONFLICT;
764
+ $errcnt++;
765
+ } elseif ($spx->prec > $spy->prec) {
766
+ $apy->type = PHP_ParserGenerator_Action::RD_RESOLVED;
767
+ } elseif ($spx->prec < $spy->prec) {
768
+ $apx->type = PHP_ParserGenerator_Action::RD_RESOLVED;
769
+ }
770
+ } else {
771
+ if ($apx->type!== PHP_ParserGenerator_Action::SH_RESOLVED &&
772
+ $apx->type!== PHP_ParserGenerator_Action::RD_RESOLVED &&
773
+ $apx->type!== PHP_ParserGenerator_Action::CONFLICT &&
774
+ $apy->type!== PHP_ParserGenerator_Action::SH_RESOLVED &&
775
+ $apy->type!== PHP_ParserGenerator_Action::RD_RESOLVED &&
776
+ $apy->type!== PHP_ParserGenerator_Action::CONFLICT) {
777
+ throw new Exception('$apx->type!== PHP_ParserGenerator_Action::SH_RESOLVED &&
778
+ $apx->type!== PHP_ParserGenerator_Action::RD_RESOLVED &&
779
+ $apx->type!== PHP_ParserGenerator_Action::CONFLICT &&
780
+ $apy->type!== PHP_ParserGenerator_Action::SH_RESOLVED &&
781
+ $apy->type!== PHP_ParserGenerator_Action::RD_RESOLVED &&
782
+ $apy->type!== PHP_ParserGenerator_Action::CONFLICT');
783
+ }
784
+ /* The REDUCE/SHIFT case cannot happen because SHIFTs come before
785
+ ** REDUCEs on the list. If we reach this point it must be because
786
+ ** the parser conflict had already been resolved. */
787
+ }
788
+ return $errcnt;
789
+ }
790
+
791
+ /**
792
+ * Reduce the size of the action tables, if possible, by making use
793
+ * of defaults.
794
+ *
795
+ * In this version, we take the most frequent REDUCE action and make
796
+ * it the default.
797
+ */
798
+ function CompressTables()
799
+ {
800
+ for ($i = 0; $i < $this->nstate; $i++) {
801
+ $stp = $this->sorted[$i]->data;
802
+ $nbest = 0;
803
+ $rbest = 0;
804
+
805
+ for ($ap = $stp->ap; $ap; $ap = $ap->next) {
806
+ if ($ap->type != PHP_ParserGenerator_Action::REDUCE) {
807
+ continue;
808
+ }
809
+ $rp = $ap->x;
810
+ if ($rp === $rbest) {
811
+ continue;
812
+ }
813
+ $n = 1;
814
+ for ($ap2 = $ap->next; $ap2; $ap2 = $ap2->next) {
815
+ if ($ap2->type != PHP_ParserGenerator_Action::REDUCE) {
816
+ continue;
817
+ }
818
+ $rp2 = $ap2->x;
819
+ if ($rp2 === $rbest) {
820
+ continue;
821
+ }
822
+ if ($rp2 === $rp) {
823
+ $n++;
824
+ }
825
+ }
826
+ if ($n > $nbest) {
827
+ $nbest = $n;
828
+ $rbest = $rp;
829
+ }
830
+ }
831
+
832
+ /* Do not make a default if the number of rules to default
833
+ ** is not at least 1 */
834
+ if ($nbest < 1) {
835
+ continue;
836
+ }
837
+
838
+
839
+ /* Combine matching REDUCE actions into a single default */
840
+ for ($ap = $stp->ap; $ap; $ap = $ap->next) {
841
+ if ($ap->type == PHP_ParserGenerator_Action::REDUCE && $ap->x === $rbest) {
842
+ break;
843
+ }
844
+ }
845
+ if ($ap === 0) {
846
+ throw new Exception('$ap is not an object');
847
+ }
848
+ $ap->sp = PHP_ParserGenerator_Symbol::Symbol_new("{default}");
849
+ for ($ap = $ap->next; $ap; $ap = $ap->next) {
850
+ if ($ap->type == PHP_ParserGenerator_Action::REDUCE && $ap->x === $rbest) {
851
+ $ap->type = PHP_ParserGenerator_Action::NOT_USED;
852
+ }
853
+ }
854
+ $stp->ap = PHP_ParserGenerator_Action::Action_sort($stp->ap);
855
+ }
856
+ }
857
+
858
+ /**
859
+ * Renumber and resort states so that states with fewer choices
860
+ * occur at the end. Except, keep state 0 as the first state.
861
+ */
862
+ function ResortStates()
863
+ {
864
+ for ($i = 0; $i < $this->nstate; $i++) {
865
+ $stp = $this->sorted[$i]->data;
866
+ $stp->nTknAct = $stp->nNtAct = 0;
867
+ $stp->iDflt = $this->nstate + $this->nrule;
868
+ $stp->iTknOfst = PHP_ParserGenerator_Data::NO_OFFSET;
869
+ $stp->iNtOfst = PHP_ParserGenerator_Data::NO_OFFSET;
870
+ for ($ap = $stp->ap; $ap; $ap = $ap->next) {
871
+ if ($this->compute_action($ap) >= 0) {
872
+ if ($ap->sp->index < $this->nterminal) {
873
+ $stp->nTknAct++;
874
+ } elseif ($ap->sp->index < $this->nsymbol) {
875
+ $stp->nNtAct++;
876
+ } else {
877
+ $stp->iDflt = $this->compute_action($ap);
878
+ }
879
+ }
880
+ }
881
+ $this->sorted[$i] = $stp;
882
+ }
883
+ $save = $this->sorted[0];
884
+ unset($this->sorted[0]);
885
+ usort($this->sorted, array('PHP_ParserGenerator_State', 'stateResortCompare'));
886
+ array_unshift($this->sorted, $save);
887
+ for($i = 0; $i < $this->nstate; $i++) {
888
+ $this->sorted[$i]->statenum = $i;
889
+ }
890
+ }
891
+
892
+ /**
893
+ * Given an action, compute the integer value for that action
894
+ * which is to be put in the action table of the generated machine.
895
+ * Return negative if no action should be generated.
896
+ * @param PHP_ParserGenerator_Action
897
+ */
898
+ function compute_action($ap)
899
+ {
900
+ switch ($ap->type) {
901
+ case PHP_ParserGenerator_Action::SHIFT:
902
+ $act = $ap->x->statenum;
903
+ break;
904
+ case PHP_ParserGenerator_Action::REDUCE:
905
+ $act = $ap->x->index + $this->nstate;
906
+ break;
907
+ case PHP_ParserGenerator_Action::ERROR:
908
+ $act = $this->nstate + $this->nrule;
909
+ break;
910
+ case PHP_ParserGenerator_Action::ACCEPT:
911
+ $act = $this->nstate + $this->nrule + 1;
912
+ break;
913
+ default:
914
+ $act = -1;
915
+ break;
916
+ }
917
+ return $act;
918
+ }
919
+
920
+ /**
921
+ * Generate the "Parse.out" log file
922
+ */
923
+ function ReportOutput()
924
+ {
925
+ $fp = fopen($this->filenosuffix . ".out", "wb");
926
+ if (!$fp) {
927
+ return;
928
+ }
929
+ for ($i = 0; $i < $this->nstate; $i++) {
930
+ $stp = $this->sorted[$i];
931
+ fprintf($fp, "State %d:\n", $stp->statenum);
932
+ if ($this->basisflag) {
933
+ $cfp = $stp->bp;
934
+ } else {
935
+ $cfp = $stp->cfp;
936
+ }
937
+ while ($cfp) {
938
+ if ($cfp->dot == $cfp->rp->nrhs) {
939
+ $buf = sprintf('(%d)', $cfp->rp->index);
940
+ fprintf($fp, ' %5s ', $buf);
941
+ } else {
942
+ fwrite($fp,' ');
943
+ }
944
+ $cfp->ConfigPrint($fp);
945
+ fwrite($fp, "\n");
946
+ if (0) {
947
+ //SetPrint(fp,cfp->fws,$this);
948
+ //PlinkPrint(fp,cfp->fplp,"To ");
949
+ //PlinkPrint(fp,cfp->bplp,"From");
950
+ }
951
+ if ($this->basisflag) {
952
+ $cfp = $cfp->bp;
953
+ } else {
954
+ $cfp = $cfp->next;
955
+ }
956
+ }
957
+ fwrite($fp, "\n");
958
+ for ($ap = $stp->ap; $ap; $ap = $ap->next) {
959
+ if ($ap->PrintAction($fp, 30)) {
960
+ fprintf($fp,"\n");
961
+ }
962
+ }
963
+ fwrite($fp,"\n");
964
+ }
965
+ fclose($fp);
966
+ }
967
+
968
+ /**
969
+ * The next function finds the template file and opens it, returning
970
+ * a pointer to the opened file.
971
+ * @return resource
972
+ */
973
+ private function tplt_open()
974
+ {
975
+ $templatename = $this->parser_template ? $this->parser_template : dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . "Lempar.php";
976
+
977
+ $buf = $this->filenosuffix . '.lt';
978
+ if (file_exists($buf) && is_readable($buf)) {
979
+ $tpltname = $buf;
980
+ } elseif (file_exists($templatename) && is_readable($templatename)) {
981
+ $tpltname = $templatename;
982
+ } elseif ($fp = @fopen($templatename, 'rb', true)) {
983
+ return $fp;
984
+ }
985
+ if (!isset($tpltname)) {
986
+ echo "Can't find the parser driver template file \"%s\".\n",
987
+ $templatename;
988
+ $this->errorcnt++;
989
+ return 0;
990
+ }
991
+ $in = @fopen($tpltname,"rb");
992
+ if (!$in) {
993
+ printf("Can't open the template file \"%s\".\n", $tpltname);
994
+ $this->errorcnt++;
995
+ return 0;
996
+ }
997
+ return $in;
998
+ }
999
+
1000
+ #define LINESIZE 1000
1001
+ /**#@+
1002
+ * The next cluster of routines are for reading the template file
1003
+ * and writing the results to the generated parser
1004
+ */
1005
+ /**
1006
+ * The first function transfers data from "in" to "out" until
1007
+ * a line is seen which begins with "%%". The line number is
1008
+ * tracked.
1009
+ *
1010
+ * if name!=0, then any word that begin with "Parse" is changed to
1011
+ * begin with *name instead.
1012
+ */
1013
+ private function tplt_xfer($name, $in, $out, &$lineno)
1014
+ {
1015
+ while (($line = fgets($in, 1024)) && ($line[0] != '%' || $line[1] != '%')) {
1016
+ $lineno++;
1017
+ $iStart = 0;
1018
+ if ($name) {
1019
+ for ($i = 0; $i < strlen($line); $i++) {
1020
+ if ($line[$i] == 'P' && substr($line, $i, 5) == "Parse"
1021
+ && ($i === 0 || preg_match('/[^a-zA-Z]/', $line[$i - 1]))) {
1022
+ if ($i > $iStart) {
1023
+ fwrite($out, substr($line, $iStart, $i - $iStart));
1024
+ }
1025
+ fwrite($out, $name);
1026
+ $i += 4;
1027
+ $iStart = $i + 1;
1028
+ }
1029
+ }
1030
+ }
1031
+ fwrite($out, substr($line, $iStart));
1032
+ }
1033
+ }
1034
+
1035
+ /**
1036
+ * Print a #line directive line to the output file.
1037
+ */
1038
+ private function tplt_linedir($out, $lineno, $filename)
1039
+ {
1040
+ fwrite($out, '#line ' . $lineno . ' "' . $filename . "\"\n");
1041
+ }
1042
+
1043
+ /**
1044
+ * Print a string to the file and keep the linenumber up to date
1045
+ */
1046
+ private function tplt_print($out, $str, $strln, &$lineno)
1047
+ {
1048
+ if ($str == '') {
1049
+ return;
1050
+ }
1051
+ $this->tplt_linedir($out, $strln, $this->filename);
1052
+ $lineno++;
1053
+ fwrite($out, $str);
1054
+ $lineno += count(explode("\n", $str)) - 1;
1055
+ $this->tplt_linedir($out, $lineno + 2, $this->outname);
1056
+ $lineno += 2;
1057
+ }
1058
+ /**#@-*/
1059
+
1060
+ /**
1061
+ * Compute all followsets.
1062
+ *
1063
+ * A followset is the set of all symbols which can come immediately
1064
+ * after a configuration.
1065
+ */
1066
+ function FindFollowSets()
1067
+ {
1068
+ for ($i = 0; $i < $this->nstate; $i++) {
1069
+ for ($cfp = $this->sorted[$i]->data->cfp; $cfp; $cfp = $cfp->next) {
1070
+ $cfp->status = PHP_ParserGenerator_Config::INCOMPLETE;
1071
+ }
1072
+ }
1073
+
1074
+ do {
1075
+ $progress = 0;
1076
+ for ($i = 0; $i < $this->nstate; $i++) {
1077
+ for ($cfp = $this->sorted[$i]->data->cfp; $cfp; $cfp = $cfp->next) {
1078
+ if ($cfp->status == PHP_ParserGenerator_Config::COMPLETE) {
1079
+ continue;
1080
+ }
1081
+ for ($plp = $cfp->fplp; $plp; $plp = $plp->next) {
1082
+ $a = array_diff_key($cfp->fws, $plp->cfp->fws);
1083
+ if (count($a)) {
1084
+ $plp->cfp->fws += $a;
1085
+ $plp->cfp->status = PHP_ParserGenerator_Config::INCOMPLETE;
1086
+ $progress = 1;
1087
+ }
1088
+ }
1089
+ $cfp->status = PHP_ParserGenerator_Config::COMPLETE;
1090
+ }
1091
+ }
1092
+ } while ($progress);
1093
+ }
1094
+
1095
+ /**
1096
+ * Generate C source code for the parser
1097
+ * @param int Output in makeheaders format if true
1098
+ */
1099
+ function ReportTable($mhflag)
1100
+ {
1101
+ // FILE *out, *in;
1102
+ // char line[LINESIZE];
1103
+ // int lineno;
1104
+ // struct state *stp;
1105
+ // struct action *ap;
1106
+ // struct rule *rp;
1107
+ // struct acttab *pActtab;
1108
+ // int i, j, n;
1109
+ // char *name;
1110
+ // int mnTknOfst, mxTknOfst;
1111
+ // int mnNtOfst, mxNtOfst;
1112
+ // struct axset *ax;
1113
+
1114
+ $in = $this->tplt_open();
1115
+ if (!$in) {
1116
+ return;
1117
+ }
1118
+ $out = fopen($this->filenosuffix . ".php", "wb");
1119
+ if (!$out) {
1120
+ fclose($in);
1121
+ return;
1122
+ }
1123
+ $this->outname = $this->filenosuffix . ".php";
1124
+ $lineno = 1;
1125
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
1126
+
1127
+ /* Generate the include code, if any */
1128
+ $this->tplt_print($out, $this->include_code, $this->includeln, $lineno);
1129
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
1130
+
1131
+ /* Generate the class declaration code */
1132
+ $this->tplt_print($out, $this->declare_classcode, $this->declare_classln,
1133
+ $lineno);
1134
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
1135
+
1136
+ /* Generate the internal parser class include code, if any */
1137
+ $this->tplt_print($out, $this->include_classcode, $this->include_classln,
1138
+ $lineno);
1139
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
1140
+
1141
+ /* Generate #defines for all tokens */
1142
+ //if ($mhflag) {
1143
+ //fprintf($out, "#if INTERFACE\n");
1144
+ $lineno++;
1145
+ if ($this->tokenprefix) {
1146
+ $prefix = $this->tokenprefix;
1147
+ } else {
1148
+ $prefix = '';
1149
+ }
1150
+ for ($i = 1; $i < $this->nterminal; $i++) {
1151
+ fprintf($out, " const %s%-30s = %2d;\n", $prefix, $this->symbols[$i]->name, $i);
1152
+ $lineno++;
1153
+ }
1154
+ //fwrite($out, "#endif\n");
1155
+ $lineno++;
1156
+ //}
1157
+ fwrite($out, " const YY_NO_ACTION = " .
1158
+ ($this->nstate + $this->nrule + 2) . ";\n");
1159
+ $lineno++;
1160
+ fwrite($out, " const YY_ACCEPT_ACTION = " .
1161
+ ($this->nstate + $this->nrule + 1) . ";\n");
1162
+ $lineno++;
1163
+ fwrite($out, " const YY_ERROR_ACTION = " .
1164
+ ($this->nstate + $this->nrule) . ";\n");
1165
+ $lineno++;
1166
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
1167
+
1168
+ /* Generate the action table and its associates:
1169
+ **
1170
+ ** yy_action[] A single table containing all actions.
1171
+ ** yy_lookahead[] A table containing the lookahead for each entry in
1172
+ ** yy_action. Used to detect hash collisions.
1173
+ ** yy_shift_ofst[] For each state, the offset into yy_action for
1174
+ ** shifting terminals.
1175
+ ** yy_reduce_ofst[] For each state, the offset into yy_action for
1176
+ ** shifting non-terminals after a reduce.
1177
+ ** yy_default[] Default action for each state.
1178
+ */
1179
+
1180
+ /* Compute the actions on all states and count them up */
1181
+
1182
+ $ax = array();
1183
+ for ($i = 0; $i < $this->nstate; $i++) {
1184
+ $stp = $this->sorted[$i];
1185
+ $ax[$i * 2] = array();
1186
+ $ax[$i * 2]['stp'] = $stp;
1187
+ $ax[$i * 2]['isTkn'] = 1;
1188
+ $ax[$i * 2]['nAction'] = $stp->nTknAct;
1189
+ $ax[$i * 2 + 1] = array();
1190
+ $ax[$i * 2 + 1]['stp'] = $stp;
1191
+ $ax[$i * 2 + 1]['isTkn'] = 0;
1192
+ $ax[$i * 2 + 1]['nAction'] = $stp->nNtAct;
1193
+ }
1194
+ $mxTknOfst = $mnTknOfst = 0;
1195
+ $mxNtOfst = $mnNtOfst = 0;
1196
+
1197
+ /* Compute the action table. In order to try to keep the size of the
1198
+ ** action table to a minimum, the heuristic of placing the largest action
1199
+ ** sets first is used.
1200
+ */
1201
+
1202
+ usort($ax, array('PHP_ParserGenerator_Data', 'axset_compare'));
1203
+ $pActtab = new PHP_ParserGenerator_ActionTable;
1204
+ for ($i = 0; $i < $this->nstate * 2 && $ax[$i]['nAction'] > 0; $i++) {
1205
+ $stp = $ax[$i]['stp'];
1206
+ if ($ax[$i]['isTkn']) {
1207
+ for ($ap = $stp->ap; $ap; $ap = $ap->next) {
1208
+ if ($ap->sp->index >= $this->nterminal) {
1209
+ continue;
1210
+ }
1211
+ $action = $this->compute_action($ap);
1212
+ if ($action < 0) {
1213
+ continue;
1214
+ }
1215
+ $pActtab->acttab_action($ap->sp->index, $action);
1216
+ }
1217
+ $stp->iTknOfst = $pActtab->acttab_insert();
1218
+ if ($stp->iTknOfst < $mnTknOfst) {
1219
+ $mnTknOfst = $stp->iTknOfst;
1220
+ }
1221
+ if ($stp->iTknOfst > $mxTknOfst) {
1222
+ $mxTknOfst = $stp->iTknOfst;
1223
+ }
1224
+ } else {
1225
+ for ($ap = $stp->ap; $ap; $ap = $ap->next) {
1226
+ if ($ap->sp->index < $this->nterminal) {
1227
+ continue;
1228
+ }
1229
+ if ($ap->sp->index == $this->nsymbol) {
1230
+ continue;
1231
+ }
1232
+ $action = $this->compute_action($ap);
1233
+ if ($action < 0) {
1234
+ continue;
1235
+ }
1236
+ $pActtab->acttab_action($ap->sp->index, $action);
1237
+ }
1238
+ $stp->iNtOfst = $pActtab->acttab_insert();
1239
+ if ($stp->iNtOfst < $mnNtOfst) {
1240
+ $mnNtOfst = $stp->iNtOfst;
1241
+ }
1242
+ if ($stp->iNtOfst > $mxNtOfst) {
1243
+ $mxNtOfst = $stp->iNtOfst;
1244
+ }
1245
+ }
1246
+ }
1247
+ /* Output the yy_action table */
1248
+
1249
+ fprintf($out, " const YY_SZ_ACTTAB = %d;\n", $pActtab->nAction);
1250
+ $lineno++;
1251
+ fwrite($out, "static public \$yy_action = array(\n");
1252
+ $lineno++;
1253
+ $n = $pActtab->nAction;
1254
+ for($i = $j = 0; $i < $n; $i++) {
1255
+ $action = $pActtab->aAction[$i]['action'];
1256
+ if ($action < 0) {
1257
+ $action = $this->nsymbol + $this->nrule + 2;
1258
+ }
1259
+ // change next line
1260
+ if ($j === 0) {
1261
+ fprintf($out, " /* %5d */ ", $i);
1262
+ }
1263
+ fprintf($out, " %4d,", $action);
1264
+ if ($j == 9 || $i == $n - 1) {
1265
+ fwrite($out, "\n");
1266
+ $lineno++;
1267
+ $j = 0;
1268
+ } else {
1269
+ $j++;
1270
+ }
1271
+ }
1272
+ fwrite($out, " );\n"); $lineno++;
1273
+
1274
+ /* Output the yy_lookahead table */
1275
+
1276
+ fwrite($out, " static public \$yy_lookahead = array(\n");
1277
+ $lineno++;
1278
+ for ($i = $j = 0; $i < $n; $i++) {
1279
+ $la = $pActtab->aAction[$i]['lookahead'];
1280
+ if ($la < 0) {
1281
+ $la = $this->nsymbol;
1282
+ }
1283
+ // change next line
1284
+ if ($j === 0) {
1285
+ fprintf($out, " /* %5d */ ", $i);
1286
+ }
1287
+ fprintf($out, " %4d,", $la);
1288
+ if ($j == 9 || $i == $n - 1) {
1289
+ fwrite($out, "\n");
1290
+ $lineno++;
1291
+ $j = 0;
1292
+ } else {
1293
+ $j++;
1294
+ }
1295
+ }
1296
+ fwrite($out, ");\n");
1297
+ $lineno++;
1298
+
1299
+ /* Output the yy_shift_ofst[] table */
1300
+ fprintf($out, " const YY_SHIFT_USE_DFLT = %d;\n", $mnTknOfst - 1);
1301
+ $lineno++;
1302
+ $n = $this->nstate;
1303
+ while ($n > 0 && $this->sorted[$n - 1]->iTknOfst == PHP_ParserGenerator_Data::NO_OFFSET) {
1304
+ $n--;
1305
+ }
1306
+ fprintf($out, " const YY_SHIFT_MAX = %d;\n", $n - 1);
1307
+ $lineno++;
1308
+ fwrite($out, " static public \$yy_shift_ofst = array(\n");
1309
+ $lineno++;
1310
+ for ($i = $j = 0; $i < $n; $i++) {
1311
+ $stp = $this->sorted[$i];
1312
+ $ofst = $stp->iTknOfst;
1313
+ if ($ofst === PHP_ParserGenerator_Data::NO_OFFSET) {
1314
+ $ofst = $mnTknOfst - 1;
1315
+ }
1316
+ // change next line
1317
+ if ($j === 0) {
1318
+ fprintf($out, " /* %5d */ ", $i);
1319
+ }
1320
+ fprintf($out, " %4d,", $ofst);
1321
+ if ($j == 9 || $i == $n - 1) {
1322
+ fwrite($out, "\n");
1323
+ $lineno++;
1324
+ $j = 0;
1325
+ } else {
1326
+ $j++;
1327
+ }
1328
+ }
1329
+ fwrite($out, ");\n");
1330
+ $lineno++;
1331
+
1332
+
1333
+ /* Output the yy_reduce_ofst[] table */
1334
+
1335
+ fprintf($out, " const YY_REDUCE_USE_DFLT = %d;\n", $mnNtOfst - 1);
1336
+ $lineno++;
1337
+ $n = $this->nstate;
1338
+ while ($n > 0 && $this->sorted[$n - 1]->iNtOfst == PHP_ParserGenerator_Data::NO_OFFSET) {
1339
+ $n--;
1340
+ }
1341
+ fprintf($out, " const YY_REDUCE_MAX = %d;\n", $n - 1);
1342
+ $lineno++;
1343
+ fwrite($out, " static public \$yy_reduce_ofst = array(\n");
1344
+ $lineno++;
1345
+ for ($i = $j = 0; $i < $n; $i++) {
1346
+ $stp = $this->sorted[$i];
1347
+ $ofst = $stp->iNtOfst;
1348
+ if ($ofst == PHP_ParserGenerator_Data::NO_OFFSET) {
1349
+ $ofst = $mnNtOfst - 1;
1350
+ }
1351
+ // change next line
1352
+ if ($j == 0) {
1353
+ fprintf($out, " /* %5d */ ", $i);
1354
+ }
1355
+ fprintf($out, " %4d,", $ofst);
1356
+ if ($j == 9 || $i == $n - 1) {
1357
+ fwrite($out, "\n");
1358
+ $lineno++;
1359
+ $j = 0;
1360
+ } else {
1361
+ $j++;
1362
+ }
1363
+ }
1364
+ fwrite($out, ");\n");
1365
+ $lineno++;
1366
+
1367
+ /* Output the expected tokens table */
1368
+
1369
+ fwrite($out, " static public \$yyExpectedTokens = array(\n");
1370
+ $lineno++;
1371
+ for ($i = 0; $i < $this->nstate; $i++) {
1372
+ $stp = $this->sorted[$i];
1373
+ fwrite($out, " /* $i */ array(");
1374
+ for ($ap = $stp->ap; $ap; $ap = $ap->next) {
1375
+ if ($ap->sp->index < $this->nterminal) {
1376
+ if ($ap->type == PHP_ParserGenerator_Action::SHIFT ||
1377
+ $ap->type == PHP_ParserGenerator_Action::REDUCE) {
1378
+ fwrite($out, $ap->sp->index . ', ');
1379
+ }
1380
+ }
1381
+ }
1382
+ fwrite($out, "),\n");
1383
+ $lineno++;
1384
+ }
1385
+ fwrite($out, ");\n");
1386
+ $lineno++;
1387
+
1388
+ /* Output the default action table */
1389
+
1390
+ fwrite($out, " static public \$yy_default = array(\n");
1391
+ $lineno++;
1392
+ $n = $this->nstate;
1393
+ for ($i = $j = 0; $i < $n; $i++) {
1394
+ $stp = $this->sorted[$i];
1395
+ // change next line
1396
+ if ($j == 0) {
1397
+ fprintf($out, " /* %5d */ ", $i);
1398
+ }
1399
+ fprintf($out, " %4d,", $stp->iDflt);
1400
+ if ($j == 9 || $i == $n - 1) {
1401
+ fprintf($out, "\n"); $lineno++;
1402
+ $j = 0;
1403
+ } else {
1404
+ $j++;
1405
+ }
1406
+ }
1407
+ fwrite($out, ");\n");
1408
+ $lineno++;
1409
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
1410
+
1411
+ /* Generate the defines */
1412
+ fprintf($out, " const YYNOCODE = %d;\n", $this->nsymbol + 1);
1413
+ $lineno++;
1414
+ if ($this->stacksize) {
1415
+ if($this->stacksize <= 0) {
1416
+ PHP_ParserGenerator::ErrorMsg($this->filename, 0,
1417
+ "Illegal stack size: [%s]. The stack size should be an integer constant.",
1418
+ $this->stacksize);
1419
+ $this->errorcnt++;
1420
+ $this->stacksize = "100";
1421
+ }
1422
+ fprintf($out, " const YYSTACKDEPTH = %s;\n", $this->stacksize);
1423
+ $lineno++;
1424
+ } else {
1425
+ fwrite($out," const YYSTACKDEPTH = 100;\n");
1426
+ $lineno++;
1427
+ }
1428
+ fprintf($out, " const YYNSTATE = %d;\n", $this->nstate);
1429
+ $lineno++;
1430
+ fprintf($out, " const YYNRULE = %d;\n", $this->nrule);
1431
+ $lineno++;
1432
+ fprintf($out, " const YYERRORSYMBOL = %d;\n", $this->errsym->index);
1433
+ $lineno++;
1434
+ fprintf($out, " const YYERRSYMDT = 'yy%d';\n", $this->errsym->dtnum);
1435
+ $lineno++;
1436
+ if ($this->has_fallback) {
1437
+ fwrite($out, " const YYFALLBACK = 1;\n");
1438
+ } else {
1439
+ fwrite($out, " const YYFALLBACK = 0;\n");
1440
+ }
1441
+ $lineno++;
1442
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
1443
+
1444
+ /* Generate the table of fallback tokens.
1445
+ */
1446
+
1447
+ if ($this->has_fallback) {
1448
+ for ($i = 0; $i < $this->nterminal; $i++) {
1449
+ $p = $this->symbols[$i];
1450
+ if ($p->fallback === 0) {
1451
+ // change next line
1452
+ fprintf($out, " 0, /* %10s => nothing */\n", $p->name);
1453
+ } else {
1454
+ // change next line
1455
+ fprintf($out, " %3d, /* %10s => %s */\n",
1456
+ $p->fallback->index, $p->name, $p->fallback->name);
1457
+ }
1458
+ $lineno++;
1459
+ }
1460
+ }
1461
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
1462
+
1463
+
1464
+ /* Generate a table containing the symbolic name of every symbol
1465
+ ($yyTokenName)
1466
+ */
1467
+
1468
+ for ($i = 0; $i < $this->nsymbol; $i++) {
1469
+ fprintf($out," %-15s", "'" . $this->symbols[$i]->name . "',");
1470
+ if (($i & 3) == 3) {
1471
+ fwrite($out,"\n");
1472
+ $lineno++;
1473
+ }
1474
+ }
1475
+ if (($i & 3) != 0) {
1476
+ fwrite($out, "\n");
1477
+ $lineno++;
1478
+ }
1479
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
1480
+
1481
+ /* Generate a table containing a text string that describes every
1482
+ ** rule in the rule set of the grammer. This information is used
1483
+ ** when tracing REDUCE actions.
1484
+ */
1485
+
1486
+ for ($i = 0, $rp = $this->rule; $rp; $rp = $rp->next, $i++) {
1487
+ if ($rp->index !== $i) {
1488
+ throw new Exception('rp->index != i and should be');
1489
+ }
1490
+ // change next line
1491
+ fprintf($out, " /* %3d */ \"%s ::=", $i, $rp->lhs->name);
1492
+ for ($j = 0; $j < $rp->nrhs; $j++) {
1493
+ $sp = $rp->rhs[$j];
1494
+ fwrite($out,' ' . $sp->name);
1495
+ if ($sp->type == PHP_ParserGenerator_Symbol::MULTITERMINAL) {
1496
+ for($k = 1; $k < $sp->nsubsym; $k++) {
1497
+ fwrite($out, '|' . $sp->subsym[$k]->name);
1498
+ }
1499
+ }
1500
+ }
1501
+ fwrite($out, "\",\n");
1502
+ $lineno++;
1503
+ }
1504
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
1505
+
1506
+ /* Generate code which executes every time a symbol is popped from
1507
+ ** the stack while processing errors or while destroying the parser.
1508
+ ** (In other words, generate the %destructor actions)
1509
+ */
1510
+
1511
+ if ($this->tokendest) {
1512
+ for ($i = 0; $i < $this->nsymbol; $i++) {
1513
+ $sp = $this->symbols[$i];
1514
+ if ($sp === 0 || $sp->type != PHP_ParserGenerator_Symbol::TERMINAL) {
1515
+ continue;
1516
+ }
1517
+ fprintf($out, " case %d:\n", $sp->index);
1518
+ $lineno++;
1519
+ }
1520
+ for ($i = 0; $i < $this->nsymbol &&
1521
+ $this->symbols[$i]->type != PHP_ParserGenerator_Symbol::TERMINAL; $i++);
1522
+ if ($i < $this->nsymbol) {
1523
+ $this->emit_destructor_code($out, $this->symbols[$i], $lineno);
1524
+ fprintf($out, " break;\n");
1525
+ $lineno++;
1526
+ }
1527
+ }
1528
+ if ($this->vardest) {
1529
+ $dflt_sp = 0;
1530
+ for ($i = 0; $i < $this->nsymbol; $i++) {
1531
+ $sp = $this->symbols[$i];
1532
+ if ($sp === 0 || $sp->type == PHP_ParserGenerator_Symbol::TERMINAL ||
1533
+ $sp->index <= 0 || $sp->destructor != 0) {
1534
+ continue;
1535
+ }
1536
+ fprintf($out, " case %d:\n", $sp->index);
1537
+ $lineno++;
1538
+ $dflt_sp = $sp;
1539
+ }
1540
+ if ($dflt_sp != 0) {
1541
+ $this->emit_destructor_code($out, $dflt_sp, $lineno);
1542
+ fwrite($out, " break;\n");
1543
+ $lineno++;
1544
+ }
1545
+ }
1546
+ for ($i = 0; $i < $this->nsymbol; $i++) {
1547
+ $sp = $this->symbols[$i];
1548
+ if ($sp === 0 || $sp->type == PHP_ParserGenerator_Symbol::TERMINAL ||
1549
+ $sp->destructor === 0) {
1550
+ continue;
1551
+ }
1552
+ fprintf($out, " case %d:\n", $sp->index);
1553
+ $lineno++;
1554
+
1555
+ /* Combine duplicate destructors into a single case */
1556
+
1557
+ for ($j = $i + 1; $j < $this->nsymbol; $j++) {
1558
+ $sp2 = $this->symbols[$j];
1559
+ if ($sp2 && $sp2->type != PHP_ParserGenerator_Symbol::TERMINAL && $sp2->destructor
1560
+ && $sp2->dtnum == $sp->dtnum
1561
+ && $sp->destructor == $sp2->destructor) {
1562
+ fprintf($out, " case %d:\n", $sp2->index);
1563
+ $lineno++;
1564
+ $sp2->destructor = 0;
1565
+ }
1566
+ }
1567
+
1568
+ $this->emit_destructor_code($out, $this->symbols[$i], $lineno);
1569
+ fprintf($out, " break;\n");
1570
+ $lineno++;
1571
+ }
1572
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
1573
+
1574
+ /* Generate code which executes whenever the parser stack overflows */
1575
+
1576
+ $this->tplt_print($out, $this->overflow, $this->overflowln, $lineno);
1577
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
1578
+
1579
+ /* Generate the table of rule information
1580
+ **
1581
+ ** Note: This code depends on the fact that rules are number
1582
+ ** sequentually beginning with 0.
1583
+ */
1584
+
1585
+ for ($rp = $this->rule; $rp; $rp = $rp->next) {
1586
+ fprintf($out, " array( 'lhs' => %d, 'rhs' => %d ),\n",
1587
+ $rp->lhs->index, $rp->nrhs);
1588
+ $lineno++;
1589
+ }
1590
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
1591
+
1592
+
1593
+ /* Generate code which executes during each REDUCE action */
1594
+
1595
+ for ($rp = $this->rule; $rp; $rp = $rp->next) {
1596
+ if ($rp->code) {
1597
+ $this->translate_code($rp);
1598
+ }
1599
+ }
1600
+
1601
+ /* Generate the method map for each REDUCE action */
1602
+
1603
+ for ($rp = $this->rule; $rp; $rp = $rp->next) {
1604
+ if ($rp->code === 0) {
1605
+ continue;
1606
+ }
1607
+ fwrite($out, ' ' . $rp->index . ' => ' . $rp->index . ",\n");
1608
+ $lineno++;
1609
+ for ($rp2 = $rp->next; $rp2; $rp2 = $rp2->next) {
1610
+ if ($rp2->code === $rp->code) {
1611
+ fwrite($out, ' ' . $rp2->index . ' => ' .
1612
+ $rp->index . ",\n");
1613
+ $lineno++;
1614
+ $rp2->code = 0;
1615
+ }
1616
+ }
1617
+ }
1618
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
1619
+
1620
+ for ($rp = $this->rule; $rp; $rp = $rp->next) {
1621
+ if ($rp->code === 0) {
1622
+ continue;
1623
+ }
1624
+ $this->emit_code($out, $rp, $lineno);
1625
+ }
1626
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
1627
+
1628
+
1629
+ /* Generate code which executes if a parse fails */
1630
+
1631
+ $this->tplt_print($out, $this->failure, $this->failureln, $lineno);
1632
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
1633
+
1634
+ /* Generate code which executes when a syntax error occurs */
1635
+
1636
+ $this->tplt_print($out, $this->error, $this->errorln, $lineno);
1637
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
1638
+
1639
+ /* Generate code which executes when the parser accepts its input */
1640
+
1641
+ $this->tplt_print($out, $this->accept, $this->acceptln, $lineno);
1642
+ $this->tplt_xfer($this->name, $in, $out, $lineno);
1643
+
1644
+ /* Append any addition code the user desires */
1645
+
1646
+ $this->tplt_print($out, $this->extracode, $this->extracodeln, $lineno);
1647
+
1648
+ fclose($in);
1649
+ fclose($out);
1650
+ }
1651
+
1652
+ /**
1653
+ * Generate code which executes when the rule "rp" is reduced. Write
1654
+ * the code to "out". Make sure lineno stays up-to-date.
1655
+ */
1656
+ function emit_code($out, PHP_ParserGenerator_Rule $rp, &$lineno)
1657
+ {
1658
+ $linecnt = 0;
1659
+
1660
+ /* Generate code to do the reduce action */
1661
+ if ($rp->code) {
1662
+ $this->tplt_linedir($out, $rp->line, $this->filename);
1663
+ fwrite($out, " function yy_r$rp->index(){" . $rp->code);
1664
+ $linecnt += count(explode("\n", $rp->code)) - 1;
1665
+ $lineno += 3 + $linecnt;
1666
+ fwrite($out, " }\n");
1667
+ $this->tplt_linedir($out, $lineno, $this->outname);
1668
+ } /* End if( rp->code ) */
1669
+ }
1670
+
1671
+ /**
1672
+ * Append text to a dynamically allocated string. If zText is 0 then
1673
+ * reset the string to be empty again. Always return the complete text
1674
+ * of the string (which is overwritten with each call).
1675
+ *
1676
+ * n bytes of zText are stored. If n==0 then all of zText is stored.
1677
+ *
1678
+ * If n==-1, then the previous character is overwritten.
1679
+ * @param string
1680
+ * @param int
1681
+ */
1682
+ function append_str($zText, $n)
1683
+ {
1684
+ static $z = '';
1685
+ $zInt = '';
1686
+
1687
+ if ($zText === '') {
1688
+ $ret = $z;
1689
+ $z = '';
1690
+ return $ret;
1691
+ }
1692
+ if ($n <= 0) {
1693
+ if ($n < 0) {
1694
+ if (!strlen($z)) {
1695
+ throw new Exception('z is zero-length');
1696
+ }
1697
+ $z = substr($z, 0, strlen($z) - 1);
1698
+ if (!$z) {
1699
+ $z = '';
1700
+ }
1701
+ }
1702
+ $n = strlen($zText);
1703
+ }
1704
+ $i = 0;
1705
+ $z .= substr($zText, 0, $n);
1706
+ return $z;
1707
+ }
1708
+
1709
+ /**
1710
+ * zCode is a string that is the action associated with a rule. Expand
1711
+ * the symbols in this string so that the refer to elements of the parser
1712
+ * stack.
1713
+ */
1714
+ function translate_code(PHP_ParserGenerator_Rule $rp)
1715
+ {
1716
+ $lhsused = 0; /* True if the LHS element has been used */
1717
+ $used = array(); /* True for each RHS element which is used */
1718
+
1719
+ $this->append_str('', 0);
1720
+ for ($i = 0; $i < strlen($rp->code); $i++) {
1721
+ $cp = $rp->code[$i];
1722
+ if (preg_match('/[A-Za-z]/', $cp) &&
1723
+ ($i === 0 || (!preg_match('/[A-Za-z0-9_]/', $rp->code[$i - 1])))) {
1724
+ //*xp = 0;
1725
+ // previous line is in essence a temporary substr, so
1726
+ // we will simulate it
1727
+ $test = substr($rp->code, $i);
1728
+ preg_match('/[A-Za-z0-9_]+/', $test, $matches);
1729
+ $tempcp = $matches[0];
1730
+ $j = strlen($tempcp) + $i;
1731
+ if ($rp->lhsalias && $tempcp == $rp->lhsalias) {
1732
+ $this->append_str("\$this->_retvalue", 0);
1733
+ $cp = $rp->code[$j];
1734
+ $i = $j;
1735
+ $lhsused = 1;
1736
+ } else {
1737
+ for ($ii = 0; $ii < $rp->nrhs; $ii++) {
1738
+ if ($rp->rhsalias[$ii] && $tempcp == $rp->rhsalias[$ii]) {
1739
+ if ($rp->code[0] == '@') {
1740
+ /* If the argument is of the form @X then substitute
1741
+ ** the token number of X, not the value of X */
1742
+ $this->append_str("\$this->yystack[\$this->yyidx + " .
1743
+ ($ii - $rp->nrhs + 1) . "]->major", -1);
1744
+ } else {
1745
+ $sp = $rp->rhs[$ii];
1746
+ if ($sp->type == PHP_ParserGenerator_Symbol::MULTITERMINAL) {
1747
+ $dtnum = $sp->subsym[0]->dtnum;
1748
+ } else {
1749
+ $dtnum = $sp->dtnum;
1750
+ }
1751
+ $this->append_str("\$this->yystack[\$this->yyidx + " .
1752
+ ($ii - $rp->nrhs + 1) . "]->minor", 0);
1753
+ }
1754
+ $cp = $rp->code[$j];
1755
+ $i = $j;
1756
+ $used[$ii] = 1;
1757
+ break;
1758
+ }
1759
+ }
1760
+ }
1761
+ }
1762
+ $this->append_str($cp, 1);
1763
+ } /* End loop */
1764
+
1765
+ /* Check to make sure the LHS has been used */
1766
+ if ($rp->lhsalias && !$lhsused) {
1767
+ PHP_ParserGenerator::ErrorMsg($this->filename, $rp->ruleline,
1768
+ "Label \"%s\" for \"%s(%s)\" is never used.",
1769
+ $rp->lhsalias, $rp->lhs->name, $rp->lhsalias);
1770
+ $this->errorcnt++;
1771
+ }
1772
+
1773
+ /* Generate destructor code for RHS symbols which are not used in the
1774
+ ** reduce code */
1775
+ for($i = 0; $i < $rp->nrhs; $i++) {
1776
+ if ($rp->rhsalias[$i] && !isset($used[$i])) {
1777
+ PHP_ParserGenerator::ErrorMsg($this->filename, $rp->ruleline,
1778
+ "Label %s for \"%s(%s)\" is never used.",
1779
+ $rp->rhsalias[$i], $rp->rhs[$i]->name, $rp->rhsalias[$i]);
1780
+ $this->errorcnt++;
1781
+ } elseif ($rp->rhsalias[$i] == 0) {
1782
+ if ($rp->rhs[$i]->type == PHP_ParserGenerator_Symbol::TERMINAL) {
1783
+ $hasdestructor = $this->tokendest != 0;
1784
+ }else{
1785
+ $hasdestructor = $this->vardest !== 0 || $rp->rhs[$i]->destructor !== 0;
1786
+ }
1787
+ if ($hasdestructor) {
1788
+ $this->append_str(" \$this->yy_destructor(" .
1789
+ ($rp->rhs[$i]->index) . ", \$this->yystack[\$this->yyidx + " .
1790
+ ($i - $rp->nrhs + 1) . "]->minor);\n", 0);
1791
+ } else {
1792
+ /* No destructor defined for this term */
1793
+ }
1794
+ }
1795
+ }
1796
+ $cp = $this->append_str('', 0);
1797
+ $rp->code = $cp;
1798
+ }
1799
+
1800
+ /**
1801
+ * The following routine emits code for the destructor for the
1802
+ * symbol sp
1803
+ */
1804
+ function emit_destructor_code($out, PHP_ParserGenerator_Symbol $sp, &$lineno)
1805
+ // FILE *out;
1806
+ // struct symbol *sp;
1807
+ // struct lemon *lemp;
1808
+ // int *lineno;
1809
+ {
1810
+ $cp = 0;
1811
+
1812
+ $linecnt = 0;
1813
+ if ($sp->type == PHP_ParserGenerator_Symbol::TERMINAL) {
1814
+ $cp = $this->tokendest;
1815
+ if ($cp === 0) {
1816
+ return;
1817
+ }
1818
+ $this->tplt_linedir($out, $this->tokendestln, $this->filename);
1819
+ fwrite($out, "{");
1820
+ } elseif ($sp->destructor) {
1821
+ $cp = $sp->destructor;
1822
+ $this->tplt_linedir($out, $sp->destructorln, $this->filename);
1823
+ fwrite($out, "{");
1824
+ } elseif ($this->vardest) {
1825
+ $cp = $this->vardest;
1826
+ if ($cp === 0) {
1827
+ return;
1828
+ }
1829
+ $this->tplt_linedir($out, $this->vardestln, $this->filename);
1830
+ fwrite($out, "{");
1831
+ } else {
1832
+ throw new Exception('emit_destructor'); /* Cannot happen */
1833
+ }
1834
+ for ($i = 0; $i < strlen($cp); $i++) {
1835
+ if ($cp[$i]=='$' && $cp[$i + 1]=='$' ) {
1836
+ fprintf($out, "(yypminor->yy%d)", $sp->dtnum);
1837
+ $i++;
1838
+ continue;
1839
+ }
1840
+ if ($cp[$i] == "\n") {
1841
+ $linecnt++;
1842
+ }
1843
+ fwrite($out, $cp[$i]);
1844
+ }
1845
+ $lineno += 3 + $linecnt;
1846
+ fwrite($out, "}\n");
1847
+ $this->tplt_linedir($out, $lineno, $this->outname);
1848
+ }
1849
+
1850
+ /**
1851
+ * Compare to axset structures for sorting purposes
1852
+ */
1853
+ static function axset_compare($a, $b)
1854
+ {
1855
+ return $b['nAction'] - $a['nAction'];
1856
+ }
1857
+ }