guard-mthaml 0.1.0

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