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.
- checksums.yaml +7 -0
- data/README.md +34 -0
- data/lib/guard/mthaml.rb +140 -0
- data/lib/guard/mthaml/compiler/MtHaml.php +255 -0
- data/lib/guard/mthaml/templates/Guardfile +12 -0
- data/lib/guard/mthaml/version.rb +5 -0
- data/vendor/autoload.php +7 -0
- data/vendor/coffeescript/coffeescript/LICENSE +22 -0
- data/vendor/coffeescript/coffeescript/README.md +96 -0
- data/vendor/coffeescript/coffeescript/composer.json +23 -0
- data/vendor/coffeescript/coffeescript/grammar.y +309 -0
- data/vendor/coffeescript/coffeescript/make.php +115 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/Compiler.php +76 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/Error.php +15 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/Helpers.php +116 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/Init.php +96 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/Lexer.php +1356 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/Nodes.php +105 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/Parser.php +3326 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/Rewriter.php +552 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/Scope.php +196 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/SyntaxError.php +9 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/Value.php +20 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Access.php +31 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Arr.php +69 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Assign.php +353 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Base.php +288 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Block.php +294 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Call.php +283 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Class.php +282 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Closure.php +49 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Code.php +203 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Comment.php +39 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Existence.php +42 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Extends.php +26 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/For.php +250 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/If.php +161 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/In.php +99 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Index.php +27 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Literal.php +96 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Obj.php +126 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Op.php +292 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Param.php +119 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Parens.php +45 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Range.php +225 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Return.php +56 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Slice.php +47 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Splat.php +100 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Switch.php +121 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Throw.php +37 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Try.php +79 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Value.php +210 -0
- data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/While.php +112 -0
- data/vendor/coffeescript/coffeescript/tests/cases/arrays.coffee +77 -0
- data/vendor/coffeescript/coffeescript/tests/cases/assignment.coffee +352 -0
- data/vendor/coffeescript/coffeescript/tests/cases/booleans.coffee +21 -0
- data/vendor/coffeescript/coffeescript/tests/cases/classes.coffee +681 -0
- data/vendor/coffeescript/coffeescript/tests/cases/comments.coffee +207 -0
- data/vendor/coffeescript/coffeescript/tests/cases/compilation.coffee +72 -0
- data/vendor/coffeescript/coffeescript/tests/cases/comprehensions.coffee +501 -0
- data/vendor/coffeescript/coffeescript/tests/cases/control_flow.coffee +430 -0
- data/vendor/coffeescript/coffeescript/tests/cases/eval.coffee +29 -0
- data/vendor/coffeescript/coffeescript/tests/cases/exception_handling.coffee +102 -0
- data/vendor/coffeescript/coffeescript/tests/cases/formatting.coffee +146 -0
- data/vendor/coffeescript/coffeescript/tests/cases/function_invocation.coffee +552 -0
- data/vendor/coffeescript/coffeescript/tests/cases/functions.coffee +188 -0
- data/vendor/coffeescript/coffeescript/tests/cases/helpers.coffee +96 -0
- data/vendor/coffeescript/coffeescript/tests/cases/importing.coffee +18 -0
- data/vendor/coffeescript/coffeescript/tests/cases/interpolation.coffee +138 -0
- data/vendor/coffeescript/coffeescript/tests/cases/javascript_literals.coffee +10 -0
- data/vendor/coffeescript/coffeescript/tests/cases/numbers.coffee +76 -0
- data/vendor/coffeescript/coffeescript/tests/cases/objects.coffee +271 -0
- data/vendor/coffeescript/coffeescript/tests/cases/operators.coffee +277 -0
- data/vendor/coffeescript/coffeescript/tests/cases/option_parser.coffee +43 -0
- data/vendor/coffeescript/coffeescript/tests/cases/ranges.coffee +88 -0
- data/vendor/coffeescript/coffeescript/tests/cases/regexps.coffee +63 -0
- data/vendor/coffeescript/coffeescript/tests/cases/scope.coffee +43 -0
- data/vendor/coffeescript/coffeescript/tests/cases/slicing_and_splicing.coffee +143 -0
- data/vendor/coffeescript/coffeescript/tests/cases/soaks.coffee +134 -0
- data/vendor/coffeescript/coffeescript/tests/cases/strict.coffee +155 -0
- data/vendor/coffeescript/coffeescript/tests/cases/strings.coffee +107 -0
- data/vendor/coffeescript/coffeescript/tests/css/style.css +43 -0
- data/vendor/coffeescript/coffeescript/tests/index.php +119 -0
- data/vendor/coffeescript/coffeescript/tests/js/lib/coffeescript_1.1.1.js +8 -0
- data/vendor/coffeescript/coffeescript/tests/js/lib/coffeescript_1.2.0.js +8 -0
- data/vendor/coffeescript/coffeescript/tests/js/lib/coffeescript_1.3.0.js +8 -0
- data/vendor/coffeescript/coffeescript/tests/js/lib/coffeescript_1.3.1.js +8 -0
- data/vendor/coffeescript/coffeescript/tests/js/lib/diff.js +276 -0
- data/vendor/coffeescript/coffeescript/tests/js/main.js +123 -0
- data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/LICENSE.txt +10 -0
- data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/Lempar.php +948 -0
- data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/Action.php +257 -0
- data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/ActionTable.php +299 -0
- data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/Config.php +574 -0
- data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/Data.php +1857 -0
- data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/Parser.php +851 -0
- data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/PropagationLink.php +126 -0
- data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/Rule.php +144 -0
- data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/State.php +283 -0
- data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/Symbol.php +288 -0
- data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/cli.php +5 -0
- data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/ParserGenerator.php +811 -0
- data/vendor/composer/ClassLoader.php +383 -0
- data/vendor/composer/autoload_classmap.php +9 -0
- data/vendor/composer/autoload_namespaces.php +12 -0
- data/vendor/composer/autoload_psr4.php +10 -0
- data/vendor/composer/autoload_real.php +50 -0
- data/vendor/composer/installed.json +166 -0
- data/vendor/michelf/php-markdown/License.md +36 -0
- data/vendor/michelf/php-markdown/Michelf/Markdown.inc.php +10 -0
- data/vendor/michelf/php-markdown/Michelf/Markdown.php +3117 -0
- data/vendor/michelf/php-markdown/Michelf/MarkdownExtra.inc.php +11 -0
- data/vendor/michelf/php-markdown/Michelf/MarkdownExtra.php +38 -0
- data/vendor/michelf/php-markdown/Michelf/MarkdownInterface.inc.php +9 -0
- data/vendor/michelf/php-markdown/Michelf/MarkdownInterface.php +37 -0
- data/vendor/michelf/php-markdown/Readme.md +305 -0
- data/vendor/michelf/php-markdown/Readme.php +31 -0
- data/vendor/michelf/php-markdown/composer.json +31 -0
- data/vendor/mthaml/mthaml/CHANGELOG +48 -0
- data/vendor/mthaml/mthaml/LICENSE +44 -0
- data/vendor/mthaml/mthaml/README.markdown +262 -0
- data/vendor/mthaml/mthaml/composer.json +45 -0
- data/vendor/mthaml/mthaml/docs/Makefile +153 -0
- data/vendor/mthaml/mthaml/docs/_static/mthaml.css +30 -0
- data/vendor/mthaml/mthaml/docs/_theme/mthaml/theme.conf +4 -0
- data/vendor/mthaml/mthaml/docs/conf.py +242 -0
- data/vendor/mthaml/mthaml/docs/index.rst +18 -0
- data/vendor/mthaml/mthaml/docs/twig-syntax.rst +274 -0
- data/vendor/mthaml/mthaml/examples/README.md +5 -0
- data/vendor/mthaml/mthaml/examples/autoload.php +8 -0
- data/vendor/mthaml/mthaml/examples/example-php.haml +5 -0
- data/vendor/mthaml/mthaml/examples/example-php.php +37 -0
- data/vendor/mthaml/mthaml/examples/example-twig-noext.twig +11 -0
- data/vendor/mthaml/mthaml/examples/example-twig.haml +9 -0
- data/vendor/mthaml/mthaml/examples/example-twig.php +60 -0
- data/vendor/mthaml/mthaml/examples/example.twig.haml +8 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Autoloader.php +22 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Environment.php +178 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Escaping.php +33 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Exception.php +9 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Exception/SyntaxErrorException.php +9 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Filter/AbstractFilter.php +43 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Cdata.php +16 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Filter/CoffeeScript.php +33 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Css.php +26 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Escaped.php +22 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Filter/FilterInterface.php +15 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Javascript.php +26 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Less.php +27 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Less/LeafoLess.php +20 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Less/OyejorgeLess.php +23 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Markdown.php +58 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Markdown/CebeMarkdown.php +22 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Markdown/Ciconia.php +21 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Markdown/MichelfMarkdown.php +21 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Markdown/Parsedown.php +21 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Php.php +37 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Plain.php +24 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Preserve.php +19 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Scss.php +37 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Twig.php +47 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Indentation/Indentation.php +96 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Indentation/IndentationException.php +9 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Indentation/IndentationInterface.php +50 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Indentation/Undefined.php +41 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Node/Comment.php +71 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Node/Doctype.php +96 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Node/EscapableAbstract.php +19 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Node/Filter.php +51 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Node/Insert.php +42 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Node/InterpolatedString.php +73 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Node/NestAbstract.php +117 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Node/NestInterface.php +10 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Node/NodeAbstract.php +77 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Node/ObjectRefClass.php +42 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Node/ObjectRefId.php +42 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Node/Root.php +35 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Node/Run.php +71 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Node/Statement.php +45 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Node/Tag.php +90 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Node/TagAttribute.php +62 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Node/TagAttributeInterpolation.php +24 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Node/TagAttributeList.php +24 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Node/Text.php +37 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/Autoclose.php +25 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/Escaping.php +105 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/MergeAttrs.php +110 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/Midblock.php +37 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/NodeVisitorAbstract.php +226 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/NodeVisitorInterface.php +97 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/PhpRenderer.php +288 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/Printer.php +265 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/RendererAbstract.php +581 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/TwigRenderer.php +252 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Parser.php +862 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Parser/Buffer.php +147 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Runtime.php +218 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Runtime/AttributeInterpolation.php +16 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Runtime/AttributeList.php +16 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Support/Php/Executor.php +157 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Support/Twig/Extension.php +47 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Support/Twig/Lexer.php +48 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Support/Twig/Loader.php +81 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Target/Php.php +23 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Target/TargetAbstract.php +87 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Target/TargetInterface.php +12 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/Target/Twig.php +23 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/TreeBuilder.php +100 -0
- data/vendor/mthaml/mthaml/lib/MtHaml/TreeBuilderException.php +9 -0
- data/vendor/mthaml/mthaml/phpunit.xml +25 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/EnvironmentTest.php +59 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/HamlSpecTest.php +83 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/IndentationTest.php +140 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/Node/DoctypeTest.php +51 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/Node/NodeTest.php +110 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/NodeVisitor/PhpRendererTest.php +113 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/NodeVisitor/TwigRendererTest.php +68 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/NodeVisitorsTest.php +44 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/Parser/BufferTest.php +77 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/ParserTest.php +47 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/RuntimeTest.php +356 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/Support/Php/ExecutorTest.php +83 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/Support/Twig/LoaderTest.php +65 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/TestCase.php +49 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/TestCaseTest.php +50 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/Support/Php/Executor.001.haml +1 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/attr_list_php.test +20 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/attr_list_twig.test +12 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/boolean_attr_php.test +16 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/boolean_attr_twig.test +16 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/bug28_php.test +15 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/bug28_twig.test +15 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/bug42.test +13 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/bug8_twig.test +10 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/coffeescript_filter.test +31 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/comments.test +26 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/cond_cmt.test +25 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/doctype.test +18 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/doctype_html4.test +20 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/doctype_invalid.test +12 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/doctype_invalid_xhtml.test +12 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/doctype_php.test +18 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/doctype_xhtml.test +30 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/filters.test +51 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/insert_non_echo_php.test +11 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/insert_non_echo_twig.test +11 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/interpolation_in_html_attrs_php.test +31 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/interpolation_in_html_attrs_twig.test +31 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/less_filter_leafo.test +33 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/less_filter_oyejorge.test +49 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/markdown_filter_cebemarkdown.test +35 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/markdown_filter_ciconia.test +36 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/markdown_filter_michelf.test +34 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/markdown_filter_parsedown.test +31 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/markdown_optimization_filter_michelf.test +23 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/mergeattrs.test +18 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/nuke_inner_whitespace.test +77 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/nuke_outer_whitespace.test +122 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/object_ref_php.test +14 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/object_ref_twig.test +14 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/php.test +109 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/php_autoescaping.test +22 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/php_autoescaping_once.test +25 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/php_blocks.test +29 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/php_filters.test +42 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/scss_filter.test +32 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/strip_inline_comments_php.test +22 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/test.test +24 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/trailing_semicolon_php.test +14 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/try_catch_php.test +17 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/twig.test +112 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/twig_blocks.test +29 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/twig_filters.test +37 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/twig_whitespace.test +32 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/whitespace.test +63 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/nodevisitors/autoclose.test +30 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/nodevisitors/escaping.test +52 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/nodevisitors/escaping_attr_once.test +52 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/nodevisitors/escaping_html_false.test +52 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/nodevisitors/mergeattrs.test +26 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/nodevisitors/midblock.test +54 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/nodevisitors/midblock_002.test +32 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/attr_list.test +14 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/attrs.test +42 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/attrs_002.test +35 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/attrs_003.test +30 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/attrs_html_linebreak.test +17 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/blocks.test +27 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/blocks_002.test +15 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/boolean_attr.test +19 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/bug28.test +15 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/bug8.test +11 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/cond_cmt.test +23 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/doctype.test +11 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/double_equal.test +7 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/empty_line_after_multiline.test +10 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_001.test +8 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_002.test +8 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_003.test +8 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_004.test +6 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_005.test +5 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_006.test +7 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_007.test +7 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_008.test +7 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_009.test +5 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_010.test +5 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_013.test +5 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_016.test +7 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_017.test +8 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_018.test +6 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_019.test +6 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_020.test +5 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/filters.test +20 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/filters_002.test +19 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/filters_003.test +13 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/filters_004.test +21 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/filters_005.test +22 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/filters_006.test +23 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/insertflags.test +17 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/interpolation.test +36 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/interpolation_in_html_attrs.test +17 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/multiline.test +18 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/multiline_code.test +59 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/multiple_attr_kinds.test +47 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/non_rendered_comment.test +31 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/ns.test +11 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/object_ref.test +22 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/object_ref_error1.test +5 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/object_ref_error2.test +5 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/quotes_in_haml.test +10 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/ruby19_attrs.test +11 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/ruby_attrs_comma.test +23 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/ruby_attrs_comma_errors_001.test +5 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/ruby_attrs_comma_errors_002.test +5 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/ruby_attrs_comma_errors_003.test +5 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/standard.test +114 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/tagflags.test +39 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/runtime/php_filters.test +28 -0
- data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/runtime/twig_filters.test +31 -0
- data/vendor/mthaml/mthaml/test/bootstrap.php +3 -0
- 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
|
+
}
|