From fc5438366c8fffe3fcefd5afd06d61027a5bb13d Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 17 Feb 2019 16:53:47 +0000 Subject: [PATCH 1/2] Add wg-grammar benchmark --- collector/benchmarks/wg-grammar/.travis.yml | 11 + collector/benchmarks/wg-grammar/Cargo.lock | 259 ++++++++++++++++++ collector/benchmarks/wg-grammar/Cargo.toml | 14 + .../benchmarks/wg-grammar/LICENSE-APACHE | 201 ++++++++++++++ collector/benchmarks/wg-grammar/LICENSE-MIT | 23 ++ collector/benchmarks/wg-grammar/README.md | 61 +++++ collector/benchmarks/wg-grammar/build.rs | 54 ++++ .../benchmarks/wg-grammar/grammar/abi.lyg | 31 +++ .../benchmarks/wg-grammar/grammar/attr.lyg | 8 + .../benchmarks/wg-grammar/grammar/expr.lyg | 130 +++++++++ .../wg-grammar/grammar/generics.lyg | 42 +++ .../benchmarks/wg-grammar/grammar/item.lyg | 118 ++++++++ .../benchmarks/wg-grammar/grammar/macro.lyg | 15 + .../benchmarks/wg-grammar/grammar/pat.lyg | 47 ++++ .../benchmarks/wg-grammar/grammar/path.lyg | 9 + .../benchmarks/wg-grammar/grammar/stmt.lyg | 8 + .../benchmarks/wg-grammar/grammar/type.lyg | 27 ++ .../benchmarks/wg-grammar/grammar/vis.lyg | 12 + .../benchmarks/wg-grammar/src/bin/tester.rs | 254 +++++++++++++++++ collector/benchmarks/wg-grammar/src/lib.rs | 5 + 20 files changed, 1329 insertions(+) create mode 100644 collector/benchmarks/wg-grammar/.travis.yml create mode 100644 collector/benchmarks/wg-grammar/Cargo.lock create mode 100644 collector/benchmarks/wg-grammar/Cargo.toml create mode 100644 collector/benchmarks/wg-grammar/LICENSE-APACHE create mode 100644 collector/benchmarks/wg-grammar/LICENSE-MIT create mode 100644 collector/benchmarks/wg-grammar/README.md create mode 100644 collector/benchmarks/wg-grammar/build.rs create mode 100644 collector/benchmarks/wg-grammar/grammar/abi.lyg create mode 100644 collector/benchmarks/wg-grammar/grammar/attr.lyg create mode 100644 collector/benchmarks/wg-grammar/grammar/expr.lyg create mode 100644 collector/benchmarks/wg-grammar/grammar/generics.lyg create mode 100644 collector/benchmarks/wg-grammar/grammar/item.lyg create mode 100644 collector/benchmarks/wg-grammar/grammar/macro.lyg create mode 100644 collector/benchmarks/wg-grammar/grammar/pat.lyg create mode 100644 collector/benchmarks/wg-grammar/grammar/path.lyg create mode 100644 collector/benchmarks/wg-grammar/grammar/stmt.lyg create mode 100644 collector/benchmarks/wg-grammar/grammar/type.lyg create mode 100644 collector/benchmarks/wg-grammar/grammar/vis.lyg create mode 100644 collector/benchmarks/wg-grammar/src/bin/tester.rs create mode 100644 collector/benchmarks/wg-grammar/src/lib.rs diff --git a/collector/benchmarks/wg-grammar/.travis.yml b/collector/benchmarks/wg-grammar/.travis.yml new file mode 100644 index 000000000..c538d2408 --- /dev/null +++ b/collector/benchmarks/wg-grammar/.travis.yml @@ -0,0 +1,11 @@ +git: + submodules: false +before_install: + - git submodule init + - git submodule update +language: rust +rust: + - stable +script: + - cargo check + - cargo run --release -- dir external/rust/src diff --git a/collector/benchmarks/wg-grammar/Cargo.lock b/collector/benchmarks/wg-grammar/Cargo.lock new file mode 100644 index 000000000..eab7342bb --- /dev/null +++ b/collector/benchmarks/wg-grammar/Cargo.lock @@ -0,0 +1,259 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "atty" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bitflags" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "clap" +version = "2.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "gll" +version = "0.0.2" +source = "git+https://github.com/rust-lang-nursery/gll#3e82b327f5dff5a7ab2c7c20498b597a0d47b581" +dependencies = [ + "indexing 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "heck" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "indexing" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.48" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "ordermap" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "proc-macro2" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "redox_syscall" +version = "0.1.51" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "redox_termios" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rust-grammar" +version = "0.1.0" +dependencies = [ + "gll 0.0.2 (git+https://github.com/rust-lang-nursery/gll)", + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "same-file" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "strsim" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "structopt" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt-derive 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "structopt-derive" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "0.15.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "termion" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "textwrap" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-segmentation" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-width" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "vec_map" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "walkdir" +version = "2.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" +"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" +"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" +"checksum gll 0.0.2 (git+https://github.com/rust-lang-nursery/gll)" = "" +"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" +"checksum indexing 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0b6b1b4b19a2928acf637b2f797829bf2c784c9a924ccad273c168f2ceb06aac" +"checksum libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "e962c7641008ac010fa60a7dfdc1712449f29c44ef2d4702394aea943ee75047" +"checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" +"checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915" +"checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1" +"checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85" +"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" +"checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267" +"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" +"checksum structopt 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "670ad348dc73012fcf78c71f06f9d942232cdd4c859d4b6975e27836c3efc0c3" +"checksum structopt-derive 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "ef98172b1a00b0bec738508d3726540edcbd186d50dfd326f2b1febbb3559f04" +"checksum syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)" = "f92e629aa1d9c827b2bb8297046c1ccffc57c99b947a680d3ccff1f136a3bee9" +"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" +"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" +"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1" +"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" +"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" +"checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1" +"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/collector/benchmarks/wg-grammar/Cargo.toml b/collector/benchmarks/wg-grammar/Cargo.toml new file mode 100644 index 000000000..40763821b --- /dev/null +++ b/collector/benchmarks/wg-grammar/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "rust-grammar" +version = "0.1.0" +authors = ["The Rust Project Developers"] + +[dependencies] +gll = { git = "https://github.com/rust-lang-nursery/gll" } +proc-macro2 = "0.4.0" +structopt = "0.2.12" +walkdir = "2.2.6" + +[build-dependencies] +gll = { git = "https://github.com/rust-lang-nursery/gll" } +walkdir = "2.2.6" diff --git a/collector/benchmarks/wg-grammar/LICENSE-APACHE b/collector/benchmarks/wg-grammar/LICENSE-APACHE new file mode 100644 index 000000000..11069edd7 --- /dev/null +++ b/collector/benchmarks/wg-grammar/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/collector/benchmarks/wg-grammar/LICENSE-MIT b/collector/benchmarks/wg-grammar/LICENSE-MIT new file mode 100644 index 000000000..31aa79387 --- /dev/null +++ b/collector/benchmarks/wg-grammar/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/collector/benchmarks/wg-grammar/README.md b/collector/benchmarks/wg-grammar/README.md new file mode 100644 index 000000000..fa674c4b6 --- /dev/null +++ b/collector/benchmarks/wg-grammar/README.md @@ -0,0 +1,61 @@ +# wg-grammar + +This is the home for the Rust Grammar Working Group. The goal of the working +group is to satisfy [RFC 1331] and produce a testable, canonical grammar for +the Rust language. The primary audiences for the grammar are: + +- Rust RFC authors who wish to propose and communicate changes. +- rustc and Rust tool developers who need an authoritative definition of the + grammar. +- To assist documentation efforts to communicate valid Rust syntax to users, + and to facilitate the [Rust language specification]. + +The grammar tools produced here are not intended to be used directly within +rustc, or any other existing tools. + +## Meeting Schedule + +Meetings take place on the [#wg-grammar channel on Discord][discord] at [20:00 +CET][time] every other Wednesday. Feel free to drop by the Discord channel if +you are interested! + +[discord]: https://discord.gg/dj9NjJR +[time]: https://time.is/compare/2000_in_CET + +## Test Suite + +This project includes a executable binary for exercising the grammar. Use +`cargo run` to build and run it. Using `--release` is encouraged as it is many +times faster. It supports several subcommands to point it at different files +or directories to examine. For example, if you check out the submodule +(explained below), you can run the tests with the following command: + + cargo run --release -- dir external/rust/src + +This repository includes a submodule to the main rust repo to use as a +collection of Rust code to test against the grammar. The command `git +submodule update --init` may be used to fetch it. However, it is not necessary +and you may run the tool against any collection of Rust code at your disposal. + +## Links + +- [Meeting notes](misc/meeting-notes.md) +- [Resources](misc/resources.md) + +## License + +Licensed under either of + + * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) + * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this crate by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. + +[RFC 1331]: https://github.com/rust-lang/rfcs/blob/master/text/1331-grammar-is-canonical.md +[Rust language specification]: https://github.com/rust-lang-nursery/reference/ diff --git a/collector/benchmarks/wg-grammar/build.rs b/collector/benchmarks/wg-grammar/build.rs new file mode 100644 index 000000000..db4979d23 --- /dev/null +++ b/collector/benchmarks/wg-grammar/build.rs @@ -0,0 +1,54 @@ +extern crate gll; +extern crate walkdir; + +use std::env; +use std::fs; +use std::path::PathBuf; +use walkdir::WalkDir; + +fn main() { + let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); + + // FIXME(eddyb) streamline this process in `gll`. + + // Find all the `.lyg` grammar fragments in `grammar/`. + let fragments = WalkDir::new("grammar") + .contents_first(true) + .into_iter() + .map(|entry| entry.unwrap()) + .filter(|entry| entry.path().extension().map_or(false, |ext| ext == "lyg")); + + // Start with the builtin rules for proc-macro grammars. + let mut grammar = gll::proc_macro::builtin(); + + // HACK(eddyb) inject a custom builtin - this should be upstreamed to gll! + { + use gll::proc_macro::{FlatTokenPat, Pat}; + + grammar.define( + "LIFETIME", + gll::grammar::eat(Pat(vec![ + FlatTokenPat::Punct { + ch: Some('\''), + joint: Some(true), + }, + FlatTokenPat::Ident(None), + ])), + ); + } + + // Add in each grammar fragment to the grammar. + for fragment in fragments { + let path = fragment.into_path(); + + // Inform Cargo about our dependency on the fragment files. + println!("cargo:rerun-if-changed={}", path.display()); + + let src = fs::read_to_string(&path).unwrap(); + let fragment: gll::grammar::Grammar<_> = src.parse().unwrap(); + grammar.extend(fragment); + } + + // Generate a Rust parser from the combined grammar and write it out. + fs::write(&out_dir.join("parse.rs"), grammar.generate_rust()).unwrap(); +} diff --git a/collector/benchmarks/wg-grammar/grammar/abi.lyg b/collector/benchmarks/wg-grammar/grammar/abi.lyg new file mode 100644 index 000000000..c2ea104d5 --- /dev/null +++ b/collector/benchmarks/wg-grammar/grammar/abi.lyg @@ -0,0 +1,31 @@ +// FIXME(eddyb) implement more specific literal support in `gll::proc_macro` +Abi = LITERAL?; + +/* +// HACK(eddyb) taken from `librustc_target/spec/abi.rs` +Abi = + // Defaults to "C" + | {} + // Platform-specific ABIs + | "\"cdecl\"" + | "\"stdcall\"" + | "\"fastcall\"" + | "\"vectorcall\"" + | "\"thiscall\"" + | "\"aapcs\"" + | "\"win64\"" + | "\"sysv64\"" + | "\"ptx-kernel\"" + | "\"msp430-interrupt\"" + | "\"x86-interrupt\"" + | "\"amdgpu-kernel\"" + // Cross-platform ABIs + | "\"Rust\"" + | "\"C\"" + | "\"system\"" + | "\"rust-intrinsic\"" + | "\"rust-call\"" + | "\"platform-intrinsic\"" + | "\"unadjusted\"" + ; +*/ diff --git a/collector/benchmarks/wg-grammar/grammar/attr.lyg b/collector/benchmarks/wg-grammar/grammar/attr.lyg new file mode 100644 index 000000000..3ecc10498 --- /dev/null +++ b/collector/benchmarks/wg-grammar/grammar/attr.lyg @@ -0,0 +1,8 @@ +OuterAttr = "#" attr:Attr; +InnerAttr = "#" "!" attr:Attr; +Attr = "[" path:Path input:AttrInput "]"; +AttrInput = + | {} + | "=" TOKEN_TREE + | MacroInput + ; diff --git a/collector/benchmarks/wg-grammar/grammar/expr.lyg b/collector/benchmarks/wg-grammar/grammar/expr.lyg new file mode 100644 index 000000000..b8b7f2cc2 --- /dev/null +++ b/collector/benchmarks/wg-grammar/grammar/expr.lyg @@ -0,0 +1,130 @@ +Expr = attrs:OuterAttr* kind:ExprKind; +ExprKind = + | Literal:LITERAL + | Paren:{ "(" attrs:InnerAttr* expr:Expr ")" } + | Borrow:{ "&" mutable:"mut"? expr:Expr } + | Box:{ "box" expr:Expr } + | Unary:{ op:UnaryOp expr:Expr } + | Try:{ expr:Expr "?" } + | Binary:{ left:Expr op:BinaryOp right:Expr } + | Assign:{ left:Expr { "=" | op:BinaryAssignOp } right:Expr } + | Range:{ start:Expr? ".." end:Expr? } + | RangeInclusive:{ start:Expr? "..=" end:Expr } + // unstable(type_ascription): + | Type:{ expr:Expr ":" ty:Type } + | Cast:{ expr:Expr "as" ty:Type } + | Field:{ base:Expr "." field:FieldName } + | Index:{ base:Expr "[" index:Expr "]" } + | Array:{ "[" attrs:InnerAttr* exprs:Expr* % "," ","? "]" } + | Repeat:{ "[" attrs:InnerAttr* elem:Expr ";" count:Expr "]" } + | Tuple:{ "(" attrs:InnerAttr* exprs:Expr* % "," ","? ")" } + | Path:QPath + | Call:{ callee:Expr "(" args:Expr* % "," ","? ")" } + | MethodCall:{ receiver:Expr "." method:PathSegment "(" args:Expr* % "," ","? ")" } + | Struct:{ path:Path "{" attrs:InnerAttr* fields:StructExprFieldsAndBase "}" } + | Block:{ { label:Label ":" }? unsafety:"unsafe"? block:Block } + // ustable(async_await): + | AsyncBlock:{ "async" block:Block } + // unstable(try_block): + | TryBlock:{ "try" block:Block } + | Continue:{ "continue" label:Label? } + | Break:{ "break" label:Label? value:Expr? } + | Return:{ "return" value:Expr? } + // unstable(generators): + | Yield:{ "yield" value:Expr? } + | If:If + | Match:{ "match" expr:Expr "{" attrs:InnerAttr* arms:MatchArm* "}" } + | Loop:{ { label:Label ":" }? "loop" body:Block } + | While:{ { label:Label ":" }? "while" cond:Cond body:Block } + | For:{ { label:Label ":" }? "for" pat:Pat "in" expr:Expr body:Block } + | Closure:{ + // unstable(generators): + generator_static:"static"? + // unstable(async_await): + asyncness:"async"? + by_val:"move"? + "|" args:ClosureArg* % "," ","? "|" { "->" ret_ty:Type }? body:Expr + } + | MacroCall:MacroCall + ; + +UnaryOp = + | Not:"!" + | Neg:"-" + | Deref:"*"; + +BinaryOp = + // Arithmetic & bitwise (these also have `BinaryAssignOp` forms) + | Add:"+" + | Sub:"-" + | Mul:"*" + | Div:"/" + | Rem:"%" + | BitXor:"^" + | BitAnd:"&" + | BitOr:"|" + | Shl:"<<" + | Shr:">>" + // Logic (short-circuiting) + | LogicAnd:"&&" + | LogicOr:"||" + // Comparisons + | Eq:"==" + | Lt:"<" + | Le:"<=" + | Ne:"!=" + | Gt:">" + | Ge:">=" + ; + +// FIXME(eddyb) figure out how to deduplicate this with `BinaryOp` +// The problem is something like `BinaryOp "="` allows a space in between, +// as the last token inside each `BinaryOp` case does not require being +// joint, but each token before the `=` here does impose that requirement. +BinaryAssignOp = + | Add:"+=" + | Sub:"-=" + | Mul:"*=" + | Div:"/=" + | Rem:"%=" + | BitXor:"^=" + | BitAnd:"&=" + | BitOr:"|=" + | Shl:"<<=" + | Shr:">>=" + ; + +FieldName = + | Ident:IDENT + // FIXME(eddyb) restrict this to only integer literals + | Numeric:LITERAL + ; + +// FIXME(eddyb) find a way to express this `A* B?` pattern better +StructExprFieldsAndBase = + | Fields:{ fields:StructExprField* % "," ","? } + | Base:{ ".." base:Expr } + | FieldsAndBase:{ fields:StructExprField+ % "," "," ".." base:Expr } + ; + +StructExprField = attrs:OuterAttr* kind:StructExprFieldKind; +StructExprFieldKind = + | Shorthand:IDENT + | Explicit:{ field:FieldName ":" expr:Expr } + ; + +Label = LIFETIME; + +If = "if" cond:Cond then:Block { "else" else_expr:ElseExpr }?; +Cond = + | Bool:Expr + | Let:{ "let" pat:Pat "=" expr:Expr } + ; +ElseExpr = + | Block:Block + | If:If + ; + +MatchArm = attrs:OuterAttr* "|"? pats:Pat+ % "|" { "if" guard:Expr }? "=>" body:Expr ","?; + +ClosureArg = pat:Pat { ":" ty:Type }?; diff --git a/collector/benchmarks/wg-grammar/grammar/generics.lyg b/collector/benchmarks/wg-grammar/grammar/generics.lyg new file mode 100644 index 000000000..b7c8c8b56 --- /dev/null +++ b/collector/benchmarks/wg-grammar/grammar/generics.lyg @@ -0,0 +1,42 @@ +Generics = "<" params:GenericParam* % "," ","? ">"; +GenericParam = attrs:OuterAttr* kind:GenericParamKind; +GenericParamKind = + | Lifetime:{ name:LIFETIME { ":" bounds:LifetimeBound* % "+" "+"? }? } + | Type:{ name:IDENT { ":" bounds:TypeBound* % "+" "+"? }? { "=" default:Type }? } + ; + +ForAllBinder = "for" generics:Generics; + +WhereClause = "where" bounds:WhereBound* % "," ","?; +WhereBound = + | Lifetime:{ lt:LIFETIME ":" bounds:LifetimeBound* % "+" "+"? } + | Type:{ binder:ForAllBinder? ty:Type ":" bounds:TypeBound* % "+" "+"? } + // unstable(#20041): + | TypeEq:{ binder:ForAllBinder? left:Type { "=" | "==" } right:Type } + ; + +LifetimeBound = outlives:LIFETIME; +TypeBound = + | Outlives:LIFETIME + | Trait:TypeTraitBound + | TraitParen:{ "(" bound:TypeTraitBound ")" } + ; +TypeTraitBound = unbound:"?"? binder:ForAllBinder? path:Path; + +GenericArgs = + | AngleBracket:{ "<" args_and_bindings:AngleBracketGenericArgsAndBindings? ","? ">" } + | Paren:{ "(" inputs:Type* % "," ","? ")" { "->" output:Type }? } + ; + +// FIXME(eddyb) find a way to express this `A* B*` pattern better +AngleBracketGenericArgsAndBindings = + | Args:GenericArg+ % "," + | Bindings:TypeBinding+ % "," + | ArgsAndBindings:{ args:GenericArg+ % "," "," bindings:TypeBinding+ % "," } + ; + +GenericArg = + | Lifetime:LIFETIME + | Type:Type + ; +TypeBinding = name:IDENT "=" ty:Type; diff --git a/collector/benchmarks/wg-grammar/grammar/item.lyg b/collector/benchmarks/wg-grammar/grammar/item.lyg new file mode 100644 index 000000000..0691694ab --- /dev/null +++ b/collector/benchmarks/wg-grammar/grammar/item.lyg @@ -0,0 +1,118 @@ +ModuleContents = attrs:InnerAttr* items:Item*; + +Item = attrs:OuterAttr* vis:Vis? kind:ItemKind; +ItemKind = + | Use:{ "use" use_tree:UseTree ";" } + | ExternCrate:{ "extern" "crate" name:IDENT { "as" rename:IDENT }? ";" } + | Mod:{ "mod" name:IDENT { ";" | "{" contents:ModuleContents "}" } } + | ForeignMod:{ "extern" abi:Abi "{" attrs:InnerAttr* items:ForeignItem* "}" } + | Static:{ "static" mutable:"mut"? name:IDENT ":" ty:Type "=" value:Expr ";" } + | Const:{ "const" name:IDENT ":" ty:Type "=" value:Expr ";" } + | Fn:{ header:FnHeader "fn" decl:FnDecl body:Block } + | TypeAlias:{ "type" name:IDENT generics:Generics? where_clause:WhereClause? "=" ty:Type ";" } + // unstable(existential_type): + | ExistentialType:{ "existential" "type" name:IDENT generics:Generics? where_clause:WhereClause? ":" bounds:TypeBound* % "+" "+"? ";" } + | Enum:{ "enum" name:IDENT generics:Generics? where_clause:WhereClause? "{" variants:EnumVariant* % "," ","? "}" } + | Struct:{ "struct" name:IDENT generics:Generics? body:StructBody } + | Union:{ "union" name:IDENT generics:Generics? where_clause:WhereClause? "{" fields:RecordField* % "," ","? "}" } + | Trait:{ + unsafety:"unsafe"? + // unstable(optin_builtin_traits): + auto:"auto"? + "trait" name:IDENT generics:Generics? + { ":" superbounds:TypeBound* % "+" "+"? }? + where_clause:WhereClause? "{" trait_items:TraitItem* "}" + } + // unstable(trait_alias): + | TraitAlias:{ + "trait" name:IDENT generics:Generics? + { ":" superbounds:TypeBound* % "+" "+"? }? + where_clause:WhereClause? "=" bounds:TypeBound* % "+" "+"? ";" + } + | Impl:{ + // unstable(specialization): + defaultness:"default"? + unsafety:"unsafe"? "impl" generics:Generics? + { negate:"!"? trait_path:Path "for" }? ty:Type + where_clause:WhereClause? "{" attrs:InnerAttr* impl_items:ImplItem* "}" + } + // unstable(decl_macro): + | Macro:{ "macro" name:IDENT { "(" TOKEN_TREE* ")" }? "{" TOKEN_TREE* "}" } + | MacroCall:ItemMacroCall + ; + +UseTree = + | Glob:{ prefix:UseTreePrefix? "*" } + | Nested:{ prefix:UseTreePrefix? "{" children:UseTree* % "," ","? "}" } + | Simple:{ path:Path { "as" rename:IDENT }? } + ; +UseTreePrefix = + | Path:{ path:Path "::" } + | Global:"::" + ; + +ForeignItem = attrs:OuterAttr* vis:Vis? kind:ForeignItemKind; +ForeignItemKind = + | Static:{ "static" mutable:"mut"? name:IDENT ":" ty:Type ";" } + | Fn:{ "fn" decl:FnDecl ";" } + // unstable(extern_types): + | Type:{ "type" name:IDENT ";" } + // unstable(macros_in_extern): + | MacroCall:ItemMacroCall + ; + +TraitItem = attrs:OuterAttr* kind:TraitItemKind; +TraitItemKind = + | Const:{ "const" name:IDENT ":" ty:Type { "=" default:Expr }? ";" } + | Fn:{ header:FnHeader "fn" decl:FnDecl { default_body:Block | ";" } } + | Type:{ "type" name:IDENT generics:Generics? { ":" bounds:TypeBound* % "+" "+"? }? where_clause:WhereClause? { "=" default:Type }? ";" } + | MacroCall:ItemMacroCall + ; + +ImplItem = + attrs:OuterAttr* + // unstable(specialization): + defaultness:"default"? + vis:Vis? kind:ImplItemKind + ; +ImplItemKind = + | Const:{ "const" name:IDENT ":" ty:Type "=" value:Expr ";" } + | Fn:{ header:FnHeader "fn" decl:FnDecl body:Block } + | Type:{ "type" name:IDENT generics:Generics? where_clause:WhereClause? "=" ty:Type ";" } + // unstable(existential_type): + | ExistentialType:{ "existential" "type" name:IDENT generics:Generics? where_clause:WhereClause? ":" bounds:TypeBound* % "+" "+"? ";" } + | MacroCall:ItemMacroCall + ; + +FnHeader = constness:"const"? unsafety:"unsafe"? asyncness:"async"? { "extern" abi:Abi }?; +FnDecl = name:IDENT generics:Generics? "(" args:FnArgs? ","? ")" { "->" ret_ty:Type }? where_clause:WhereClause?; + +// FIXME(eddyb) find a way to express this `A* B?` pattern better +FnArgs = + | Regular:FnArg+ % "," + | Variadic:"..." + | RegularAndVariadic:{ args:FnArg+ % "," "," "..." } + ; +FnArg = + | SelfValue:{ mutable:"mut"? "self" } + | SelfRef:{ "&" lt:LIFETIME? mutable:"mut"? "self" } + | Regular:FnSigInput + ; + +EnumVariant = attrs:OuterAttr* name:IDENT kind:EnumVariantKind { "=" discr:Expr }?; +EnumVariantKind = + | Unit:{} + | Tuple:{ "(" fields:TupleField* % "," ","? ")" } + | Record:{ "{" fields:RecordField* % "," ","? "}" } + ; + +// FIXME(eddyb) could maybe be shared more with `EnumVariantKind`? +// The problem is the semicolons for `Unit` and `Tuple`, and the where clauses. +StructBody = + | Unit:{ where_clause:WhereClause? ";" } + | Tuple:{ "(" fields:TupleField* % "," ","? ")" where_clause:WhereClause? ";" } + | Record:{ where_clause:WhereClause? "{" fields:RecordField* % "," ","? "}" } + ; + +TupleField = attrs:OuterAttr* vis:Vis? ty:Type; +RecordField = attrs:OuterAttr* vis:Vis? name:IDENT ":" ty:Type; diff --git a/collector/benchmarks/wg-grammar/grammar/macro.lyg b/collector/benchmarks/wg-grammar/grammar/macro.lyg new file mode 100644 index 000000000..87072b494 --- /dev/null +++ b/collector/benchmarks/wg-grammar/grammar/macro.lyg @@ -0,0 +1,15 @@ +MacroCall = path:Path "!" ident_input:IDENT? input:MacroInput; +MacroInput = + | "(" TOKEN_TREE* ")" + | "[" TOKEN_TREE* "]" + | "{" TOKEN_TREE* "}" + ; + +// FIXME(eddyb) could maybe be shared more with `MacroInput`? +// The problem is the semicolons for the `()` and `[]` cases. +ItemMacroCall = path:Path "!" ident_input:IDENT? input:ItemMacroInput; +ItemMacroInput = + | "(" TOKEN_TREE* ")" ";" + | "[" TOKEN_TREE* "]" ";" + | "{" TOKEN_TREE* "}" + ; diff --git a/collector/benchmarks/wg-grammar/grammar/pat.lyg b/collector/benchmarks/wg-grammar/grammar/pat.lyg new file mode 100644 index 000000000..844294944 --- /dev/null +++ b/collector/benchmarks/wg-grammar/grammar/pat.lyg @@ -0,0 +1,47 @@ +Pat = + | Wild:"_" + | Literal:{ minus:"-"? lit:LITERAL } + // unstable(exclusive_range_pattern): + | Range:{ start:PatRangeValue ".." end:PatRangeValue } + | RangeInclusive:{ start:PatRangeValue { "..." | "..=" } end:PatRangeValue } + | Binding:{ binding:Binding { "@" subpat:Pat }? } + | Paren:{ "(" pat:Pat ")" } + | Ref:{ "&" mutable:"mut"? pat:Pat } + // unstable(box_patterns): + | Box:{ "box" pat:Pat } + | Slice:{ "[" elems:SlicePatElem* % "," ","? "]" } + | Tuple:{ "(" fields:TuplePatField* % "," ","? ")" } + | Path:QPath + | TupleStruct:{ path:Path "(" fields:TuplePatField* % "," ","? ")" } + | Struct:{ path:Path "{" fields:StructPatFieldsAndEllipsis "}" } + | MacroCall:MacroCall + ; + +PatRangeValue = + | Literal:{ minus:"-"? lit:LITERAL } + | Path:QPath + ; + +Binding = boxed:"box"? reference:"ref"? mutable:"mut"? name:IDENT; + +SlicePatElem = + | Subslice:{ subpat:Pat? ".." } + | Pat:Pat + ; + +TuplePatField = + | Ellipsis:".." + | Pat:Pat + ; + +// FIXME(eddyb) find a way to express this `A* B?` pattern better +StructPatFieldsAndEllipsis = + | Fields:{ fields:StructPatField* % "," ","? } + | Ellipsis:{ ".." } + | FieldsAndEllipsis:{ fields:StructPatField+ % "," "," ".." } + ; + +StructPatField = + | Shorthand:Binding + | Explicit:{ field:FieldName ":" pat:Pat } + ; diff --git a/collector/benchmarks/wg-grammar/grammar/path.lyg b/collector/benchmarks/wg-grammar/grammar/path.lyg new file mode 100644 index 000000000..10de3e1e2 --- /dev/null +++ b/collector/benchmarks/wg-grammar/grammar/path.lyg @@ -0,0 +1,9 @@ +Path = global:"::"? path:RelativePath; +RelativePath = segments:PathSegment+ % "::"; +PathSegment = ident:IDENT { "::"? args:GenericArgs }?; + +QSelf = "<" ty:Type { "as" trait_path:Path }? ">"; +QPath = + | Unqualified:Path + | Qualified:{ qself:QSelf "::" path:RelativePath } + ; diff --git a/collector/benchmarks/wg-grammar/grammar/stmt.lyg b/collector/benchmarks/wg-grammar/grammar/stmt.lyg new file mode 100644 index 000000000..d0e2e4832 --- /dev/null +++ b/collector/benchmarks/wg-grammar/grammar/stmt.lyg @@ -0,0 +1,8 @@ +Stmt = + | Item:Item + | Local:{ attrs:OuterAttr* "let" pat:Pat { ":" ty:Type }? { "=" init:Expr }? ";" } + | Expr:Expr + | Semi:";" + ; + +Block = "{" attrs:InnerAttr* Stmt* "}"; diff --git a/collector/benchmarks/wg-grammar/grammar/type.lyg b/collector/benchmarks/wg-grammar/grammar/type.lyg new file mode 100644 index 000000000..124fb237f --- /dev/null +++ b/collector/benchmarks/wg-grammar/grammar/type.lyg @@ -0,0 +1,27 @@ +Type = + | Infer:"_" + | Never:"!" + | Paren:{ "(" ty:Type ")" } + | RawPtr:{ "*" { "const" | mutable:"mut" } pointee:Type } + | Ref:{ "&" lt:LIFETIME? mutable:"mut"? pointee:Type } + | Slice:{ "[" elem:Type "]" } + | Array:{ "[" elem:Type ";" len:Expr "]" } + | Tuple:{ "(" tys:Type* % "," ","? ")" } + | Path:QPath + | FnPtr:{ + binder:ForAllBinder? unsafety:"unsafe"? { "extern" abi:Abi }? + "fn" "(" inputs:FnSigInputs? ","? ")" { "->" ret_ty:Type }? + } + | ImplTrait:{ "impl" bounds:TypeBound+ % "+" "+"? } + | DynTrait:{ "dyn"? bounds:TypeBound+ % "+" "+"? } + // unstable(not exposed to users): + | TypeOf:{ "typeof" "(" expr:Expr ")" } + | MacroCall:MacroCall + ; + +FnSigInputs = + | Regular:FnSigInput+ % "," + | Variadic:"..." + | RegularAndVariadic:{ inputs:FnSigInput+ % "," "," "..." } + ; +FnSigInput = { pat:Pat ":" }? ty:Type; diff --git a/collector/benchmarks/wg-grammar/grammar/vis.lyg b/collector/benchmarks/wg-grammar/grammar/vis.lyg new file mode 100644 index 000000000..1d3d3f377 --- /dev/null +++ b/collector/benchmarks/wg-grammar/grammar/vis.lyg @@ -0,0 +1,12 @@ +Vis = + // unstable(crate_visibility_modifier): + | Crate:"crate" + | Pub:"pub" + | Restricted:{ "pub" "(" restriction:VisRestriction ")" } + ; +VisRestriction = + | Crate:"crate" + | Self_:"self" + | Super:"super" + | Path:{ "in" path:Path } + ; diff --git a/collector/benchmarks/wg-grammar/src/bin/tester.rs b/collector/benchmarks/wg-grammar/src/bin/tester.rs new file mode 100644 index 000000000..c5cdf43c3 --- /dev/null +++ b/collector/benchmarks/wg-grammar/src/bin/tester.rs @@ -0,0 +1,254 @@ +extern crate gll; +extern crate proc_macro2; +extern crate rust_grammar; +extern crate structopt; +extern crate walkdir; + +use gll::runtime::{MoreThanOne, ParseNodeKind, ParseNodeShape}; +use rust_grammar::parse; +use std::collections::{BTreeSet, VecDeque}; +use std::fs; +use std::io; +use std::io::prelude::*; +use std::path::{Path, PathBuf}; +use structopt::StructOpt; +use walkdir::WalkDir; + +#[derive(StructOpt)] +enum Command { + #[structopt(name = "file")] + /// Test parsing an individual Rust file + File { + #[structopt(parse(from_os_str), long = "graphviz-forest")] + /// Dump the internal parse forest as a Graphviz .dot file + graphviz_forest: Option, + + #[structopt(parse(from_os_str))] + /// Rust input file + file: PathBuf, + }, + + #[structopt(name = "dir")] + /// Test parsing a directory of Rust files + Dir { + #[structopt(short = "v", long = "verbose")] + /// Print information about each file on stderr + verbose: bool, + + #[structopt(parse(from_os_str))] + /// Directory to find Rust files in + dir: PathBuf, + }, +} + +type ModuleContentsResult<'a, 'i> = parse::ParseResult< + 'a, + 'i, + proc_macro2::TokenStream, + parse::ModuleContents<'a, 'i, proc_macro2::TokenStream>, +>; + +type ModuleContentsHandle<'a, 'i> = parse::Handle< + 'a, + 'i, + proc_macro2::TokenStream, + parse::ModuleContents<'a, 'i, proc_macro2::TokenStream>, +>; + +/// Read the contents of the file at the given `path`, parse it +/// using the `ModuleContents` rule, and pass the result to `f`. +fn parse_file_with(path: &Path, f: impl FnOnce(ModuleContentsResult) -> R) -> R { + let src = fs::read_to_string(path).unwrap(); + match src.parse::() { + Ok(tts) => parse::ModuleContents::parse_with(tts, |_, result| f(result)), + // FIXME(eddyb) provide more information in this error case. + Err(_) => f(Err(parse::ParseError::NoParse)), + } +} + +/// Output the result of a single file to stderr, +/// optionally prefixed by a given `path`. +fn report_file_result( + path: Option<&Path>, + result: ModuleContentsResult, + ambiguity_result: Result<(), MoreThanOne>, +) { + if let Some(path) = path { + eprint!("{}: ", path.display()); + } + // Avoid printing too much, especially not any parse nodes. + match (result, ambiguity_result) { + (Ok(_), Ok(_)) => eprintln!("OK"), + (Ok(_), Err(_)) => eprintln!("OK (ambiguous)"), + (Err(parse::ParseError::TooShort(handle)), _) => { + eprint!("FAIL after "); + + #[cfg(procmacro2_semver_exempt)] + { + // HACK(eddyb) work around `proc-macro2` `Span` printing limitation + let end_location = handle.source_info().end.end(); + eprintln!("{}:{}", end_location.line, end_location.column); + } + #[cfg(not(procmacro2_semver_exempt))] + { + let _ = handle; + eprintln!( + "(missing location information; \ + set `RUSTFLAGS='--cfg procmacro2_semver_exempt'`)" + ); + } + } + (Err(parse::ParseError::NoParse), _) => eprintln!("FAIL (lexer error?)"), + } +} + +fn ambiguity_check(handle: ModuleContentsHandle) -> Result<(), MoreThanOne> { + let sppf = &handle.parser.sppf; + + let mut queue = VecDeque::new(); + queue.push_back(handle.node); + let mut seen: BTreeSet<_> = queue.iter().cloned().collect(); + + while let Some(source) = queue.pop_front() { + let mut add_children = |children: &[_]| { + for &child in children { + if seen.insert(child) { + queue.push_back(child); + } + } + }; + match source.kind.shape() { + ParseNodeShape::Opaque => {} + ParseNodeShape::Alias(_) => add_children(&[source.unpack_alias()]), + ParseNodeShape::Opt(_) => { + if let Some(child) = source.unpack_opt() { + add_children(&[child]); + } + } + ParseNodeShape::Choice => add_children(&[sppf.one_choice(source)?]), + ParseNodeShape::Split(..) => { + let (left, right) = sppf.one_split(source)?; + add_children(&[left, right]) + } + } + } + + Ok(()) +} + +fn main() { + match Command::from_args() { + Command::File { + graphviz_forest, + file, + } => { + // Not much to do, try to parse the file and report the result. + parse_file_with(&file, |result| { + let mut ambiguity_result = Ok(()); + match result { + Ok(handle) | Err(parse::ParseError::TooShort(handle)) => { + ambiguity_result = ambiguity_check(handle); + + if let Some(out_path) = graphviz_forest { + handle + .parser + .sppf + .dump_graphviz(&mut fs::File::create(out_path).unwrap()) + .unwrap(); + } + } + Err(parse::ParseError::NoParse) => {} + } + report_file_result(None, result, ambiguity_result); + }); + } + Command::Dir { verbose, dir } => { + // Counters for reporting overall stats at the end. + let mut total_count = 0; + let mut unambiguous_count = 0; + let mut ambiguous_count = 0; + let mut too_short_count = 0; + let mut no_parse_count = 0; + + // Find all the `.rs` files inside the desired directory. + let files = WalkDir::new(dir) + .contents_first(true) + .into_iter() + .map(|entry| entry.unwrap()) + .filter(|entry| entry.path().extension().map_or(false, |ext| ext == "rs")); + + let mut stdout = io::stdout(); + + // Go through all the files and try to parse each of them. + for file in files { + let path = file.into_path(); + + total_count += 1; + if !verbose { + // Limit the compact output to 80 columns wide. + if total_count % 80 == 0 { + println!(""); + } + } + + // HACK(eddyb) avoid parsing some files that hit + // `lykenware/gll` worst-cases (many GBs of RAM usage) + // FIXME(eddyb) fix the problems (e.g. implement GC). + const BLACKLIST: &[&str] = &[ + "libcore/unicode/tables.rs", + "issues/issue-29466.rs", + "issues/issue-29227.rs", + ]; + if BLACKLIST.iter().any(|&b| path.ends_with(b)) { + if verbose { + eprintln!("{}: SKIP (blacklisted)...", path.display()); + } else { + print!("S"); + stdout.flush().unwrap(); + } + continue; + } + + // Indicate the current file being parsed in verbose mode. + // This can be used to find files to blacklist (see above). + if verbose { + eprint!("{}...\r", path.display()); + } + + parse_file_with(&path, |result| { + // Increment counters and figure out the character to print. + let mut ambiguity_result = Ok(()); + let (status, count) = match result { + Ok(handle) => { + ambiguity_result = ambiguity_check(handle); + if ambiguity_result.is_ok() { + ('.', &mut unambiguous_count) + } else { + ('-', &mut ambiguous_count) + } + } + Err(parse::ParseError::TooShort(_)) => ('X', &mut too_short_count), + Err(parse::ParseError::NoParse) => ('L', &mut no_parse_count), + }; + *count += 1; + + if verbose { + // Unless we're in verbose mode, in which case we print more. + report_file_result(Some(&path), result, ambiguity_result); + } else { + print!("{}", status); + stdout.flush().unwrap(); + } + }) + } + + // We're done, time to print out stats! + println!(""); + println!("Out of {} Rust files tested:", total_count); + println!("* {} parsed fully and unambiguously", unambiguous_count); + println!("* {} parsed fully (but ambiguously)", ambiguous_count); + println!("* {} parsed partially (only a prefix)", too_short_count); + println!("* {} didn't parse at all (lexer error?)", no_parse_count); + } + } +} diff --git a/collector/benchmarks/wg-grammar/src/lib.rs b/collector/benchmarks/wg-grammar/src/lib.rs new file mode 100644 index 000000000..79803f8e6 --- /dev/null +++ b/collector/benchmarks/wg-grammar/src/lib.rs @@ -0,0 +1,5 @@ +extern crate gll; + +pub mod parse { + include!(concat!(env!("OUT_DIR"), "/parse.rs")); +} From b46fb4994ac4deeacbc01be65162e9c1a129f18f Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sat, 23 Feb 2019 10:10:11 +0000 Subject: [PATCH 2/2] Cut down the size of wg-grammar test --- collector/benchmarks/wg-grammar/Cargo.lock | 211 --- collector/benchmarks/wg-grammar/Cargo.toml | 7 - collector/benchmarks/wg-grammar/build.rs | 54 - .../benchmarks/wg-grammar/grammar/abi.lyg | 31 - .../benchmarks/wg-grammar/grammar/attr.lyg | 8 - .../benchmarks/wg-grammar/grammar/expr.lyg | 131 +- .../wg-grammar/grammar/generics.lyg | 42 - .../benchmarks/wg-grammar/grammar/item.lyg | 118 -- .../benchmarks/wg-grammar/grammar/macro.lyg | 15 - .../benchmarks/wg-grammar/grammar/pat.lyg | 47 - .../benchmarks/wg-grammar/grammar/path.lyg | 9 - .../benchmarks/wg-grammar/grammar/stmt.lyg | 8 - .../benchmarks/wg-grammar/grammar/type.lyg | 27 - .../benchmarks/wg-grammar/grammar/vis.lyg | 12 - .../benchmarks/wg-grammar/src/bin/tester.rs | 254 --- collector/benchmarks/wg-grammar/src/lib.rs | 4 +- collector/benchmarks/wg-grammar/src/parse.rs | 1566 +++++++++++++++++ 17 files changed, 1579 insertions(+), 965 deletions(-) delete mode 100644 collector/benchmarks/wg-grammar/build.rs delete mode 100644 collector/benchmarks/wg-grammar/grammar/abi.lyg delete mode 100644 collector/benchmarks/wg-grammar/grammar/attr.lyg delete mode 100644 collector/benchmarks/wg-grammar/grammar/generics.lyg delete mode 100644 collector/benchmarks/wg-grammar/grammar/item.lyg delete mode 100644 collector/benchmarks/wg-grammar/grammar/macro.lyg delete mode 100644 collector/benchmarks/wg-grammar/grammar/pat.lyg delete mode 100644 collector/benchmarks/wg-grammar/grammar/path.lyg delete mode 100644 collector/benchmarks/wg-grammar/grammar/stmt.lyg delete mode 100644 collector/benchmarks/wg-grammar/grammar/type.lyg delete mode 100644 collector/benchmarks/wg-grammar/grammar/vis.lyg delete mode 100644 collector/benchmarks/wg-grammar/src/bin/tester.rs create mode 100644 collector/benchmarks/wg-grammar/src/parse.rs diff --git a/collector/benchmarks/wg-grammar/Cargo.lock b/collector/benchmarks/wg-grammar/Cargo.lock index eab7342bb..8324ee7de 100644 --- a/collector/benchmarks/wg-grammar/Cargo.lock +++ b/collector/benchmarks/wg-grammar/Cargo.lock @@ -1,42 +1,5 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -[[package]] -name = "ansi_term" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "atty" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bitflags" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "clap" -version = "2.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "gll" version = "0.0.2" @@ -47,24 +10,11 @@ dependencies = [ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "heck" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "indexing" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "libc" -version = "0.2.48" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "ordermap" version = "0.3.5" @@ -78,182 +28,21 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "quote" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "redox_syscall" -version = "0.1.51" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "redox_termios" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rust-grammar" version = "0.1.0" dependencies = [ "gll 0.0.2 (git+https://github.com/rust-lang-nursery/gll)", - "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "structopt 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "same-file" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "strsim" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "structopt" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "structopt-derive 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "structopt-derive" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "syn" -version = "0.15.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "termion" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "textwrap" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "unicode-segmentation" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "unicode-width" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "unicode-xid" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "vec_map" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "walkdir" -version = "2.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "winapi" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi-util" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [metadata] -"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" -"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" -"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" "checksum gll 0.0.2 (git+https://github.com/rust-lang-nursery/gll)" = "" -"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum indexing 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0b6b1b4b19a2928acf637b2f797829bf2c784c9a924ccad273c168f2ceb06aac" -"checksum libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "e962c7641008ac010fa60a7dfdc1712449f29c44ef2d4702394aea943ee75047" "checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" "checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915" -"checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1" -"checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85" -"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" -"checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267" -"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" -"checksum structopt 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "670ad348dc73012fcf78c71f06f9d942232cdd4c859d4b6975e27836c3efc0c3" -"checksum structopt-derive 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "ef98172b1a00b0bec738508d3726540edcbd186d50dfd326f2b1febbb3559f04" -"checksum syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)" = "f92e629aa1d9c827b2bb8297046c1ccffc57c99b947a680d3ccff1f136a3bee9" -"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" -"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" -"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1" -"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" -"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" -"checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1" -"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/collector/benchmarks/wg-grammar/Cargo.toml b/collector/benchmarks/wg-grammar/Cargo.toml index 40763821b..b70caec43 100644 --- a/collector/benchmarks/wg-grammar/Cargo.toml +++ b/collector/benchmarks/wg-grammar/Cargo.toml @@ -5,10 +5,3 @@ authors = ["The Rust Project Developers"] [dependencies] gll = { git = "https://github.com/rust-lang-nursery/gll" } -proc-macro2 = "0.4.0" -structopt = "0.2.12" -walkdir = "2.2.6" - -[build-dependencies] -gll = { git = "https://github.com/rust-lang-nursery/gll" } -walkdir = "2.2.6" diff --git a/collector/benchmarks/wg-grammar/build.rs b/collector/benchmarks/wg-grammar/build.rs deleted file mode 100644 index db4979d23..000000000 --- a/collector/benchmarks/wg-grammar/build.rs +++ /dev/null @@ -1,54 +0,0 @@ -extern crate gll; -extern crate walkdir; - -use std::env; -use std::fs; -use std::path::PathBuf; -use walkdir::WalkDir; - -fn main() { - let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); - - // FIXME(eddyb) streamline this process in `gll`. - - // Find all the `.lyg` grammar fragments in `grammar/`. - let fragments = WalkDir::new("grammar") - .contents_first(true) - .into_iter() - .map(|entry| entry.unwrap()) - .filter(|entry| entry.path().extension().map_or(false, |ext| ext == "lyg")); - - // Start with the builtin rules for proc-macro grammars. - let mut grammar = gll::proc_macro::builtin(); - - // HACK(eddyb) inject a custom builtin - this should be upstreamed to gll! - { - use gll::proc_macro::{FlatTokenPat, Pat}; - - grammar.define( - "LIFETIME", - gll::grammar::eat(Pat(vec![ - FlatTokenPat::Punct { - ch: Some('\''), - joint: Some(true), - }, - FlatTokenPat::Ident(None), - ])), - ); - } - - // Add in each grammar fragment to the grammar. - for fragment in fragments { - let path = fragment.into_path(); - - // Inform Cargo about our dependency on the fragment files. - println!("cargo:rerun-if-changed={}", path.display()); - - let src = fs::read_to_string(&path).unwrap(); - let fragment: gll::grammar::Grammar<_> = src.parse().unwrap(); - grammar.extend(fragment); - } - - // Generate a Rust parser from the combined grammar and write it out. - fs::write(&out_dir.join("parse.rs"), grammar.generate_rust()).unwrap(); -} diff --git a/collector/benchmarks/wg-grammar/grammar/abi.lyg b/collector/benchmarks/wg-grammar/grammar/abi.lyg deleted file mode 100644 index c2ea104d5..000000000 --- a/collector/benchmarks/wg-grammar/grammar/abi.lyg +++ /dev/null @@ -1,31 +0,0 @@ -// FIXME(eddyb) implement more specific literal support in `gll::proc_macro` -Abi = LITERAL?; - -/* -// HACK(eddyb) taken from `librustc_target/spec/abi.rs` -Abi = - // Defaults to "C" - | {} - // Platform-specific ABIs - | "\"cdecl\"" - | "\"stdcall\"" - | "\"fastcall\"" - | "\"vectorcall\"" - | "\"thiscall\"" - | "\"aapcs\"" - | "\"win64\"" - | "\"sysv64\"" - | "\"ptx-kernel\"" - | "\"msp430-interrupt\"" - | "\"x86-interrupt\"" - | "\"amdgpu-kernel\"" - // Cross-platform ABIs - | "\"Rust\"" - | "\"C\"" - | "\"system\"" - | "\"rust-intrinsic\"" - | "\"rust-call\"" - | "\"platform-intrinsic\"" - | "\"unadjusted\"" - ; -*/ diff --git a/collector/benchmarks/wg-grammar/grammar/attr.lyg b/collector/benchmarks/wg-grammar/grammar/attr.lyg deleted file mode 100644 index 3ecc10498..000000000 --- a/collector/benchmarks/wg-grammar/grammar/attr.lyg +++ /dev/null @@ -1,8 +0,0 @@ -OuterAttr = "#" attr:Attr; -InnerAttr = "#" "!" attr:Attr; -Attr = "[" path:Path input:AttrInput "]"; -AttrInput = - | {} - | "=" TOKEN_TREE - | MacroInput - ; diff --git a/collector/benchmarks/wg-grammar/grammar/expr.lyg b/collector/benchmarks/wg-grammar/grammar/expr.lyg index b8b7f2cc2..62218b1f5 100644 --- a/collector/benchmarks/wg-grammar/grammar/expr.lyg +++ b/collector/benchmarks/wg-grammar/grammar/expr.lyg @@ -1,130 +1,23 @@ -Expr = attrs:OuterAttr* kind:ExprKind; -ExprKind = +// Grammar file used to generate src/parse.rs + +Expr = | Literal:LITERAL - | Paren:{ "(" attrs:InnerAttr* expr:Expr ")" } + | Paren:{ "(" expr:Expr ")" } | Borrow:{ "&" mutable:"mut"? expr:Expr } | Box:{ "box" expr:Expr } - | Unary:{ op:UnaryOp expr:Expr } | Try:{ expr:Expr "?" } - | Binary:{ left:Expr op:BinaryOp right:Expr } - | Assign:{ left:Expr { "=" | op:BinaryAssignOp } right:Expr } | Range:{ start:Expr? ".." end:Expr? } | RangeInclusive:{ start:Expr? "..=" end:Expr } - // unstable(type_ascription): - | Type:{ expr:Expr ":" ty:Type } - | Cast:{ expr:Expr "as" ty:Type } - | Field:{ base:Expr "." field:FieldName } + | Cast:{ expr:Expr "as" ty:IDENT } | Index:{ base:Expr "[" index:Expr "]" } - | Array:{ "[" attrs:InnerAttr* exprs:Expr* % "," ","? "]" } - | Repeat:{ "[" attrs:InnerAttr* elem:Expr ";" count:Expr "]" } - | Tuple:{ "(" attrs:InnerAttr* exprs:Expr* % "," ","? ")" } - | Path:QPath + | Array:{ "[" exprs:Expr* % "," ","? "]" } + | Repeat:{ "[" elem:Expr ";" count:Expr "]" } + | Tuple:{ "(" exprs:Expr* % "," ","? ")" } | Call:{ callee:Expr "(" args:Expr* % "," ","? ")" } - | MethodCall:{ receiver:Expr "." method:PathSegment "(" args:Expr* % "," ","? ")" } - | Struct:{ path:Path "{" attrs:InnerAttr* fields:StructExprFieldsAndBase "}" } - | Block:{ { label:Label ":" }? unsafety:"unsafe"? block:Block } - // ustable(async_await): - | AsyncBlock:{ "async" block:Block } - // unstable(try_block): - | TryBlock:{ "try" block:Block } - | Continue:{ "continue" label:Label? } - | Break:{ "break" label:Label? value:Expr? } + | MethodCall:{ receiver:Expr "." method:IDENT "(" args:Expr* % "," ","? ")" } + | Continue:{ "continue" } + | Break:{ "break" value:Expr? } | Return:{ "return" value:Expr? } - // unstable(generators): - | Yield:{ "yield" value:Expr? } - | If:If - | Match:{ "match" expr:Expr "{" attrs:InnerAttr* arms:MatchArm* "}" } - | Loop:{ { label:Label ":" }? "loop" body:Block } - | While:{ { label:Label ":" }? "while" cond:Cond body:Block } - | For:{ { label:Label ":" }? "for" pat:Pat "in" expr:Expr body:Block } - | Closure:{ - // unstable(generators): - generator_static:"static"? - // unstable(async_await): - asyncness:"async"? - by_val:"move"? - "|" args:ClosureArg* % "," ","? "|" { "->" ret_ty:Type }? body:Expr - } - | MacroCall:MacroCall ; -UnaryOp = - | Not:"!" - | Neg:"-" - | Deref:"*"; - -BinaryOp = - // Arithmetic & bitwise (these also have `BinaryAssignOp` forms) - | Add:"+" - | Sub:"-" - | Mul:"*" - | Div:"/" - | Rem:"%" - | BitXor:"^" - | BitAnd:"&" - | BitOr:"|" - | Shl:"<<" - | Shr:">>" - // Logic (short-circuiting) - | LogicAnd:"&&" - | LogicOr:"||" - // Comparisons - | Eq:"==" - | Lt:"<" - | Le:"<=" - | Ne:"!=" - | Gt:">" - | Ge:">=" - ; - -// FIXME(eddyb) figure out how to deduplicate this with `BinaryOp` -// The problem is something like `BinaryOp "="` allows a space in between, -// as the last token inside each `BinaryOp` case does not require being -// joint, but each token before the `=` here does impose that requirement. -BinaryAssignOp = - | Add:"+=" - | Sub:"-=" - | Mul:"*=" - | Div:"/=" - | Rem:"%=" - | BitXor:"^=" - | BitAnd:"&=" - | BitOr:"|=" - | Shl:"<<=" - | Shr:">>=" - ; - -FieldName = - | Ident:IDENT - // FIXME(eddyb) restrict this to only integer literals - | Numeric:LITERAL - ; - -// FIXME(eddyb) find a way to express this `A* B?` pattern better -StructExprFieldsAndBase = - | Fields:{ fields:StructExprField* % "," ","? } - | Base:{ ".." base:Expr } - | FieldsAndBase:{ fields:StructExprField+ % "," "," ".." base:Expr } - ; - -StructExprField = attrs:OuterAttr* kind:StructExprFieldKind; -StructExprFieldKind = - | Shorthand:IDENT - | Explicit:{ field:FieldName ":" expr:Expr } - ; - -Label = LIFETIME; - -If = "if" cond:Cond then:Block { "else" else_expr:ElseExpr }?; -Cond = - | Bool:Expr - | Let:{ "let" pat:Pat "=" expr:Expr } - ; -ElseExpr = - | Block:Block - | If:If - ; - -MatchArm = attrs:OuterAttr* "|"? pats:Pat+ % "|" { "if" guard:Expr }? "=>" body:Expr ","?; - -ClosureArg = pat:Pat { ":" ty:Type }?; +ModuleContents = items:Expr*; diff --git a/collector/benchmarks/wg-grammar/grammar/generics.lyg b/collector/benchmarks/wg-grammar/grammar/generics.lyg deleted file mode 100644 index b7c8c8b56..000000000 --- a/collector/benchmarks/wg-grammar/grammar/generics.lyg +++ /dev/null @@ -1,42 +0,0 @@ -Generics = "<" params:GenericParam* % "," ","? ">"; -GenericParam = attrs:OuterAttr* kind:GenericParamKind; -GenericParamKind = - | Lifetime:{ name:LIFETIME { ":" bounds:LifetimeBound* % "+" "+"? }? } - | Type:{ name:IDENT { ":" bounds:TypeBound* % "+" "+"? }? { "=" default:Type }? } - ; - -ForAllBinder = "for" generics:Generics; - -WhereClause = "where" bounds:WhereBound* % "," ","?; -WhereBound = - | Lifetime:{ lt:LIFETIME ":" bounds:LifetimeBound* % "+" "+"? } - | Type:{ binder:ForAllBinder? ty:Type ":" bounds:TypeBound* % "+" "+"? } - // unstable(#20041): - | TypeEq:{ binder:ForAllBinder? left:Type { "=" | "==" } right:Type } - ; - -LifetimeBound = outlives:LIFETIME; -TypeBound = - | Outlives:LIFETIME - | Trait:TypeTraitBound - | TraitParen:{ "(" bound:TypeTraitBound ")" } - ; -TypeTraitBound = unbound:"?"? binder:ForAllBinder? path:Path; - -GenericArgs = - | AngleBracket:{ "<" args_and_bindings:AngleBracketGenericArgsAndBindings? ","? ">" } - | Paren:{ "(" inputs:Type* % "," ","? ")" { "->" output:Type }? } - ; - -// FIXME(eddyb) find a way to express this `A* B*` pattern better -AngleBracketGenericArgsAndBindings = - | Args:GenericArg+ % "," - | Bindings:TypeBinding+ % "," - | ArgsAndBindings:{ args:GenericArg+ % "," "," bindings:TypeBinding+ % "," } - ; - -GenericArg = - | Lifetime:LIFETIME - | Type:Type - ; -TypeBinding = name:IDENT "=" ty:Type; diff --git a/collector/benchmarks/wg-grammar/grammar/item.lyg b/collector/benchmarks/wg-grammar/grammar/item.lyg deleted file mode 100644 index 0691694ab..000000000 --- a/collector/benchmarks/wg-grammar/grammar/item.lyg +++ /dev/null @@ -1,118 +0,0 @@ -ModuleContents = attrs:InnerAttr* items:Item*; - -Item = attrs:OuterAttr* vis:Vis? kind:ItemKind; -ItemKind = - | Use:{ "use" use_tree:UseTree ";" } - | ExternCrate:{ "extern" "crate" name:IDENT { "as" rename:IDENT }? ";" } - | Mod:{ "mod" name:IDENT { ";" | "{" contents:ModuleContents "}" } } - | ForeignMod:{ "extern" abi:Abi "{" attrs:InnerAttr* items:ForeignItem* "}" } - | Static:{ "static" mutable:"mut"? name:IDENT ":" ty:Type "=" value:Expr ";" } - | Const:{ "const" name:IDENT ":" ty:Type "=" value:Expr ";" } - | Fn:{ header:FnHeader "fn" decl:FnDecl body:Block } - | TypeAlias:{ "type" name:IDENT generics:Generics? where_clause:WhereClause? "=" ty:Type ";" } - // unstable(existential_type): - | ExistentialType:{ "existential" "type" name:IDENT generics:Generics? where_clause:WhereClause? ":" bounds:TypeBound* % "+" "+"? ";" } - | Enum:{ "enum" name:IDENT generics:Generics? where_clause:WhereClause? "{" variants:EnumVariant* % "," ","? "}" } - | Struct:{ "struct" name:IDENT generics:Generics? body:StructBody } - | Union:{ "union" name:IDENT generics:Generics? where_clause:WhereClause? "{" fields:RecordField* % "," ","? "}" } - | Trait:{ - unsafety:"unsafe"? - // unstable(optin_builtin_traits): - auto:"auto"? - "trait" name:IDENT generics:Generics? - { ":" superbounds:TypeBound* % "+" "+"? }? - where_clause:WhereClause? "{" trait_items:TraitItem* "}" - } - // unstable(trait_alias): - | TraitAlias:{ - "trait" name:IDENT generics:Generics? - { ":" superbounds:TypeBound* % "+" "+"? }? - where_clause:WhereClause? "=" bounds:TypeBound* % "+" "+"? ";" - } - | Impl:{ - // unstable(specialization): - defaultness:"default"? - unsafety:"unsafe"? "impl" generics:Generics? - { negate:"!"? trait_path:Path "for" }? ty:Type - where_clause:WhereClause? "{" attrs:InnerAttr* impl_items:ImplItem* "}" - } - // unstable(decl_macro): - | Macro:{ "macro" name:IDENT { "(" TOKEN_TREE* ")" }? "{" TOKEN_TREE* "}" } - | MacroCall:ItemMacroCall - ; - -UseTree = - | Glob:{ prefix:UseTreePrefix? "*" } - | Nested:{ prefix:UseTreePrefix? "{" children:UseTree* % "," ","? "}" } - | Simple:{ path:Path { "as" rename:IDENT }? } - ; -UseTreePrefix = - | Path:{ path:Path "::" } - | Global:"::" - ; - -ForeignItem = attrs:OuterAttr* vis:Vis? kind:ForeignItemKind; -ForeignItemKind = - | Static:{ "static" mutable:"mut"? name:IDENT ":" ty:Type ";" } - | Fn:{ "fn" decl:FnDecl ";" } - // unstable(extern_types): - | Type:{ "type" name:IDENT ";" } - // unstable(macros_in_extern): - | MacroCall:ItemMacroCall - ; - -TraitItem = attrs:OuterAttr* kind:TraitItemKind; -TraitItemKind = - | Const:{ "const" name:IDENT ":" ty:Type { "=" default:Expr }? ";" } - | Fn:{ header:FnHeader "fn" decl:FnDecl { default_body:Block | ";" } } - | Type:{ "type" name:IDENT generics:Generics? { ":" bounds:TypeBound* % "+" "+"? }? where_clause:WhereClause? { "=" default:Type }? ";" } - | MacroCall:ItemMacroCall - ; - -ImplItem = - attrs:OuterAttr* - // unstable(specialization): - defaultness:"default"? - vis:Vis? kind:ImplItemKind - ; -ImplItemKind = - | Const:{ "const" name:IDENT ":" ty:Type "=" value:Expr ";" } - | Fn:{ header:FnHeader "fn" decl:FnDecl body:Block } - | Type:{ "type" name:IDENT generics:Generics? where_clause:WhereClause? "=" ty:Type ";" } - // unstable(existential_type): - | ExistentialType:{ "existential" "type" name:IDENT generics:Generics? where_clause:WhereClause? ":" bounds:TypeBound* % "+" "+"? ";" } - | MacroCall:ItemMacroCall - ; - -FnHeader = constness:"const"? unsafety:"unsafe"? asyncness:"async"? { "extern" abi:Abi }?; -FnDecl = name:IDENT generics:Generics? "(" args:FnArgs? ","? ")" { "->" ret_ty:Type }? where_clause:WhereClause?; - -// FIXME(eddyb) find a way to express this `A* B?` pattern better -FnArgs = - | Regular:FnArg+ % "," - | Variadic:"..." - | RegularAndVariadic:{ args:FnArg+ % "," "," "..." } - ; -FnArg = - | SelfValue:{ mutable:"mut"? "self" } - | SelfRef:{ "&" lt:LIFETIME? mutable:"mut"? "self" } - | Regular:FnSigInput - ; - -EnumVariant = attrs:OuterAttr* name:IDENT kind:EnumVariantKind { "=" discr:Expr }?; -EnumVariantKind = - | Unit:{} - | Tuple:{ "(" fields:TupleField* % "," ","? ")" } - | Record:{ "{" fields:RecordField* % "," ","? "}" } - ; - -// FIXME(eddyb) could maybe be shared more with `EnumVariantKind`? -// The problem is the semicolons for `Unit` and `Tuple`, and the where clauses. -StructBody = - | Unit:{ where_clause:WhereClause? ";" } - | Tuple:{ "(" fields:TupleField* % "," ","? ")" where_clause:WhereClause? ";" } - | Record:{ where_clause:WhereClause? "{" fields:RecordField* % "," ","? "}" } - ; - -TupleField = attrs:OuterAttr* vis:Vis? ty:Type; -RecordField = attrs:OuterAttr* vis:Vis? name:IDENT ":" ty:Type; diff --git a/collector/benchmarks/wg-grammar/grammar/macro.lyg b/collector/benchmarks/wg-grammar/grammar/macro.lyg deleted file mode 100644 index 87072b494..000000000 --- a/collector/benchmarks/wg-grammar/grammar/macro.lyg +++ /dev/null @@ -1,15 +0,0 @@ -MacroCall = path:Path "!" ident_input:IDENT? input:MacroInput; -MacroInput = - | "(" TOKEN_TREE* ")" - | "[" TOKEN_TREE* "]" - | "{" TOKEN_TREE* "}" - ; - -// FIXME(eddyb) could maybe be shared more with `MacroInput`? -// The problem is the semicolons for the `()` and `[]` cases. -ItemMacroCall = path:Path "!" ident_input:IDENT? input:ItemMacroInput; -ItemMacroInput = - | "(" TOKEN_TREE* ")" ";" - | "[" TOKEN_TREE* "]" ";" - | "{" TOKEN_TREE* "}" - ; diff --git a/collector/benchmarks/wg-grammar/grammar/pat.lyg b/collector/benchmarks/wg-grammar/grammar/pat.lyg deleted file mode 100644 index 844294944..000000000 --- a/collector/benchmarks/wg-grammar/grammar/pat.lyg +++ /dev/null @@ -1,47 +0,0 @@ -Pat = - | Wild:"_" - | Literal:{ minus:"-"? lit:LITERAL } - // unstable(exclusive_range_pattern): - | Range:{ start:PatRangeValue ".." end:PatRangeValue } - | RangeInclusive:{ start:PatRangeValue { "..." | "..=" } end:PatRangeValue } - | Binding:{ binding:Binding { "@" subpat:Pat }? } - | Paren:{ "(" pat:Pat ")" } - | Ref:{ "&" mutable:"mut"? pat:Pat } - // unstable(box_patterns): - | Box:{ "box" pat:Pat } - | Slice:{ "[" elems:SlicePatElem* % "," ","? "]" } - | Tuple:{ "(" fields:TuplePatField* % "," ","? ")" } - | Path:QPath - | TupleStruct:{ path:Path "(" fields:TuplePatField* % "," ","? ")" } - | Struct:{ path:Path "{" fields:StructPatFieldsAndEllipsis "}" } - | MacroCall:MacroCall - ; - -PatRangeValue = - | Literal:{ minus:"-"? lit:LITERAL } - | Path:QPath - ; - -Binding = boxed:"box"? reference:"ref"? mutable:"mut"? name:IDENT; - -SlicePatElem = - | Subslice:{ subpat:Pat? ".." } - | Pat:Pat - ; - -TuplePatField = - | Ellipsis:".." - | Pat:Pat - ; - -// FIXME(eddyb) find a way to express this `A* B?` pattern better -StructPatFieldsAndEllipsis = - | Fields:{ fields:StructPatField* % "," ","? } - | Ellipsis:{ ".." } - | FieldsAndEllipsis:{ fields:StructPatField+ % "," "," ".." } - ; - -StructPatField = - | Shorthand:Binding - | Explicit:{ field:FieldName ":" pat:Pat } - ; diff --git a/collector/benchmarks/wg-grammar/grammar/path.lyg b/collector/benchmarks/wg-grammar/grammar/path.lyg deleted file mode 100644 index 10de3e1e2..000000000 --- a/collector/benchmarks/wg-grammar/grammar/path.lyg +++ /dev/null @@ -1,9 +0,0 @@ -Path = global:"::"? path:RelativePath; -RelativePath = segments:PathSegment+ % "::"; -PathSegment = ident:IDENT { "::"? args:GenericArgs }?; - -QSelf = "<" ty:Type { "as" trait_path:Path }? ">"; -QPath = - | Unqualified:Path - | Qualified:{ qself:QSelf "::" path:RelativePath } - ; diff --git a/collector/benchmarks/wg-grammar/grammar/stmt.lyg b/collector/benchmarks/wg-grammar/grammar/stmt.lyg deleted file mode 100644 index d0e2e4832..000000000 --- a/collector/benchmarks/wg-grammar/grammar/stmt.lyg +++ /dev/null @@ -1,8 +0,0 @@ -Stmt = - | Item:Item - | Local:{ attrs:OuterAttr* "let" pat:Pat { ":" ty:Type }? { "=" init:Expr }? ";" } - | Expr:Expr - | Semi:";" - ; - -Block = "{" attrs:InnerAttr* Stmt* "}"; diff --git a/collector/benchmarks/wg-grammar/grammar/type.lyg b/collector/benchmarks/wg-grammar/grammar/type.lyg deleted file mode 100644 index 124fb237f..000000000 --- a/collector/benchmarks/wg-grammar/grammar/type.lyg +++ /dev/null @@ -1,27 +0,0 @@ -Type = - | Infer:"_" - | Never:"!" - | Paren:{ "(" ty:Type ")" } - | RawPtr:{ "*" { "const" | mutable:"mut" } pointee:Type } - | Ref:{ "&" lt:LIFETIME? mutable:"mut"? pointee:Type } - | Slice:{ "[" elem:Type "]" } - | Array:{ "[" elem:Type ";" len:Expr "]" } - | Tuple:{ "(" tys:Type* % "," ","? ")" } - | Path:QPath - | FnPtr:{ - binder:ForAllBinder? unsafety:"unsafe"? { "extern" abi:Abi }? - "fn" "(" inputs:FnSigInputs? ","? ")" { "->" ret_ty:Type }? - } - | ImplTrait:{ "impl" bounds:TypeBound+ % "+" "+"? } - | DynTrait:{ "dyn"? bounds:TypeBound+ % "+" "+"? } - // unstable(not exposed to users): - | TypeOf:{ "typeof" "(" expr:Expr ")" } - | MacroCall:MacroCall - ; - -FnSigInputs = - | Regular:FnSigInput+ % "," - | Variadic:"..." - | RegularAndVariadic:{ inputs:FnSigInput+ % "," "," "..." } - ; -FnSigInput = { pat:Pat ":" }? ty:Type; diff --git a/collector/benchmarks/wg-grammar/grammar/vis.lyg b/collector/benchmarks/wg-grammar/grammar/vis.lyg deleted file mode 100644 index 1d3d3f377..000000000 --- a/collector/benchmarks/wg-grammar/grammar/vis.lyg +++ /dev/null @@ -1,12 +0,0 @@ -Vis = - // unstable(crate_visibility_modifier): - | Crate:"crate" - | Pub:"pub" - | Restricted:{ "pub" "(" restriction:VisRestriction ")" } - ; -VisRestriction = - | Crate:"crate" - | Self_:"self" - | Super:"super" - | Path:{ "in" path:Path } - ; diff --git a/collector/benchmarks/wg-grammar/src/bin/tester.rs b/collector/benchmarks/wg-grammar/src/bin/tester.rs deleted file mode 100644 index c5cdf43c3..000000000 --- a/collector/benchmarks/wg-grammar/src/bin/tester.rs +++ /dev/null @@ -1,254 +0,0 @@ -extern crate gll; -extern crate proc_macro2; -extern crate rust_grammar; -extern crate structopt; -extern crate walkdir; - -use gll::runtime::{MoreThanOne, ParseNodeKind, ParseNodeShape}; -use rust_grammar::parse; -use std::collections::{BTreeSet, VecDeque}; -use std::fs; -use std::io; -use std::io::prelude::*; -use std::path::{Path, PathBuf}; -use structopt::StructOpt; -use walkdir::WalkDir; - -#[derive(StructOpt)] -enum Command { - #[structopt(name = "file")] - /// Test parsing an individual Rust file - File { - #[structopt(parse(from_os_str), long = "graphviz-forest")] - /// Dump the internal parse forest as a Graphviz .dot file - graphviz_forest: Option, - - #[structopt(parse(from_os_str))] - /// Rust input file - file: PathBuf, - }, - - #[structopt(name = "dir")] - /// Test parsing a directory of Rust files - Dir { - #[structopt(short = "v", long = "verbose")] - /// Print information about each file on stderr - verbose: bool, - - #[structopt(parse(from_os_str))] - /// Directory to find Rust files in - dir: PathBuf, - }, -} - -type ModuleContentsResult<'a, 'i> = parse::ParseResult< - 'a, - 'i, - proc_macro2::TokenStream, - parse::ModuleContents<'a, 'i, proc_macro2::TokenStream>, ->; - -type ModuleContentsHandle<'a, 'i> = parse::Handle< - 'a, - 'i, - proc_macro2::TokenStream, - parse::ModuleContents<'a, 'i, proc_macro2::TokenStream>, ->; - -/// Read the contents of the file at the given `path`, parse it -/// using the `ModuleContents` rule, and pass the result to `f`. -fn parse_file_with(path: &Path, f: impl FnOnce(ModuleContentsResult) -> R) -> R { - let src = fs::read_to_string(path).unwrap(); - match src.parse::() { - Ok(tts) => parse::ModuleContents::parse_with(tts, |_, result| f(result)), - // FIXME(eddyb) provide more information in this error case. - Err(_) => f(Err(parse::ParseError::NoParse)), - } -} - -/// Output the result of a single file to stderr, -/// optionally prefixed by a given `path`. -fn report_file_result( - path: Option<&Path>, - result: ModuleContentsResult, - ambiguity_result: Result<(), MoreThanOne>, -) { - if let Some(path) = path { - eprint!("{}: ", path.display()); - } - // Avoid printing too much, especially not any parse nodes. - match (result, ambiguity_result) { - (Ok(_), Ok(_)) => eprintln!("OK"), - (Ok(_), Err(_)) => eprintln!("OK (ambiguous)"), - (Err(parse::ParseError::TooShort(handle)), _) => { - eprint!("FAIL after "); - - #[cfg(procmacro2_semver_exempt)] - { - // HACK(eddyb) work around `proc-macro2` `Span` printing limitation - let end_location = handle.source_info().end.end(); - eprintln!("{}:{}", end_location.line, end_location.column); - } - #[cfg(not(procmacro2_semver_exempt))] - { - let _ = handle; - eprintln!( - "(missing location information; \ - set `RUSTFLAGS='--cfg procmacro2_semver_exempt'`)" - ); - } - } - (Err(parse::ParseError::NoParse), _) => eprintln!("FAIL (lexer error?)"), - } -} - -fn ambiguity_check(handle: ModuleContentsHandle) -> Result<(), MoreThanOne> { - let sppf = &handle.parser.sppf; - - let mut queue = VecDeque::new(); - queue.push_back(handle.node); - let mut seen: BTreeSet<_> = queue.iter().cloned().collect(); - - while let Some(source) = queue.pop_front() { - let mut add_children = |children: &[_]| { - for &child in children { - if seen.insert(child) { - queue.push_back(child); - } - } - }; - match source.kind.shape() { - ParseNodeShape::Opaque => {} - ParseNodeShape::Alias(_) => add_children(&[source.unpack_alias()]), - ParseNodeShape::Opt(_) => { - if let Some(child) = source.unpack_opt() { - add_children(&[child]); - } - } - ParseNodeShape::Choice => add_children(&[sppf.one_choice(source)?]), - ParseNodeShape::Split(..) => { - let (left, right) = sppf.one_split(source)?; - add_children(&[left, right]) - } - } - } - - Ok(()) -} - -fn main() { - match Command::from_args() { - Command::File { - graphviz_forest, - file, - } => { - // Not much to do, try to parse the file and report the result. - parse_file_with(&file, |result| { - let mut ambiguity_result = Ok(()); - match result { - Ok(handle) | Err(parse::ParseError::TooShort(handle)) => { - ambiguity_result = ambiguity_check(handle); - - if let Some(out_path) = graphviz_forest { - handle - .parser - .sppf - .dump_graphviz(&mut fs::File::create(out_path).unwrap()) - .unwrap(); - } - } - Err(parse::ParseError::NoParse) => {} - } - report_file_result(None, result, ambiguity_result); - }); - } - Command::Dir { verbose, dir } => { - // Counters for reporting overall stats at the end. - let mut total_count = 0; - let mut unambiguous_count = 0; - let mut ambiguous_count = 0; - let mut too_short_count = 0; - let mut no_parse_count = 0; - - // Find all the `.rs` files inside the desired directory. - let files = WalkDir::new(dir) - .contents_first(true) - .into_iter() - .map(|entry| entry.unwrap()) - .filter(|entry| entry.path().extension().map_or(false, |ext| ext == "rs")); - - let mut stdout = io::stdout(); - - // Go through all the files and try to parse each of them. - for file in files { - let path = file.into_path(); - - total_count += 1; - if !verbose { - // Limit the compact output to 80 columns wide. - if total_count % 80 == 0 { - println!(""); - } - } - - // HACK(eddyb) avoid parsing some files that hit - // `lykenware/gll` worst-cases (many GBs of RAM usage) - // FIXME(eddyb) fix the problems (e.g. implement GC). - const BLACKLIST: &[&str] = &[ - "libcore/unicode/tables.rs", - "issues/issue-29466.rs", - "issues/issue-29227.rs", - ]; - if BLACKLIST.iter().any(|&b| path.ends_with(b)) { - if verbose { - eprintln!("{}: SKIP (blacklisted)...", path.display()); - } else { - print!("S"); - stdout.flush().unwrap(); - } - continue; - } - - // Indicate the current file being parsed in verbose mode. - // This can be used to find files to blacklist (see above). - if verbose { - eprint!("{}...\r", path.display()); - } - - parse_file_with(&path, |result| { - // Increment counters and figure out the character to print. - let mut ambiguity_result = Ok(()); - let (status, count) = match result { - Ok(handle) => { - ambiguity_result = ambiguity_check(handle); - if ambiguity_result.is_ok() { - ('.', &mut unambiguous_count) - } else { - ('-', &mut ambiguous_count) - } - } - Err(parse::ParseError::TooShort(_)) => ('X', &mut too_short_count), - Err(parse::ParseError::NoParse) => ('L', &mut no_parse_count), - }; - *count += 1; - - if verbose { - // Unless we're in verbose mode, in which case we print more. - report_file_result(Some(&path), result, ambiguity_result); - } else { - print!("{}", status); - stdout.flush().unwrap(); - } - }) - } - - // We're done, time to print out stats! - println!(""); - println!("Out of {} Rust files tested:", total_count); - println!("* {} parsed fully and unambiguously", unambiguous_count); - println!("* {} parsed fully (but ambiguously)", ambiguous_count); - println!("* {} parsed partially (only a prefix)", too_short_count); - println!("* {} didn't parse at all (lexer error?)", no_parse_count); - } - } -} diff --git a/collector/benchmarks/wg-grammar/src/lib.rs b/collector/benchmarks/wg-grammar/src/lib.rs index 79803f8e6..9c6a767b7 100644 --- a/collector/benchmarks/wg-grammar/src/lib.rs +++ b/collector/benchmarks/wg-grammar/src/lib.rs @@ -1,5 +1,3 @@ extern crate gll; -pub mod parse { - include!(concat!(env!("OUT_DIR"), "/parse.rs")); -} +pub mod parse; diff --git a/collector/benchmarks/wg-grammar/src/parse.rs b/collector/benchmarks/wg-grammar/src/parse.rs new file mode 100644 index 000000000..7ee9f33ec --- /dev/null +++ b/collector/benchmarks/wg-grammar/src/parse.rs @@ -0,0 +1,1566 @@ +use gll::runtime::{Call, Continuation, ParseNodeKind, CodeLabel, ParseNodeShape, ParseNode, Range, traverse, nd::Arrow}; +use std::any; +use std::fmt; +use std::marker::PhantomData; +#[derive(Debug)] +pub enum ParseError { + TooShort(T), + NoParse, +} + +pub type ParseResult<'a, 'i, I, T> = + Result, ParseError>>; + +pub type Any = dyn any::Any; + +#[derive(Debug)] +pub struct Ambiguity(T); + +pub struct Handle<'a, 'i: 'a, I: 'a + ::gll::runtime::Input, T: ?Sized> { + pub node: ParseNode<'i, _P>, + pub parser: &'a ::gll::runtime::Parser<'i, _P, _C, I>, + _marker: PhantomData, +} + +impl<'a, 'i, I: ::gll::runtime::Input, T: ?Sized> Copy for Handle<'a, 'i, I, T> {} + +impl<'a, 'i, I: ::gll::runtime::Input, T: ?Sized> Clone for Handle<'a, 'i, I, T> { + fn clone(&self) -> Self { + *self + } +} + +impl<'a, 'i, I: ::gll::runtime::Input, T: ?Sized> Handle<'a, 'i, I, T> { + pub fn source(self) -> &'a I::Slice { + self.parser.input(self.node.range) + } + pub fn source_info(self) -> I::SourceInfo { + self.parser.source_info(self.node.range) + } +} + +impl<'a, 'i, I: ::gll::runtime::Input, T> From>> for Ambiguity> { + fn from(x: Ambiguity>) -> Self { + Ambiguity(Handle { + node: x.0.node, + parser: x.0.parser, + _marker: PhantomData, + }) + } +} + +impl<'a, 'i, I: ::gll::runtime::Input, T> From>> for Ambiguity> { + fn from(x: Ambiguity>) -> Self { + Ambiguity(Handle { + node: x.0.node, + parser: x.0.parser, + _marker: PhantomData, + }) + } +} + +impl<'a, 'i, I: ::gll::runtime::Input> fmt::Debug for Handle<'a, 'i, I, ()> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self.source_info()) + } +} + +impl<'a, 'i, I: ::gll::runtime::Input, T> fmt::Debug for Handle<'a, 'i, I, [T]> + where Handle<'a, 'i, I, T>: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?} => ", self.source_info())?; + match self.all_list_heads() { + ListHead::Cons(cons) => { + for (i, (elem, rest)) in cons.enumerate() { + if i > 0 { + write!(f, " | ")?; + } + enum Elem { + One(T), + Spread(L), + } + impl fmt::Debug for Elem { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Elem::One(x) => fmt::Debug::fmt(x, f), + Elem::Spread(xs) => { + write!(f, "..(")?; + fmt::Debug::fmt(xs, f)?; + write!(f, ")") + } + } + } + } + f.debug_list().entries(::std::iter::once(Elem::One(elem)).chain(rest.map(|r| { + match r { + Ok(x) => Elem::One(x), + Err(Ambiguity(xs)) => Elem::Spread(xs), + } + }))).finish()?; + } + } + ListHead::Nil => { + f.debug_list().entries(None::<()>).finish()?; + } + } + Ok(()) + } +} + +impl<'a, 'i, I: ::gll::runtime::Input, T> Iterator for Handle<'a, 'i, I, [T]> { + type Item = Result, Ambiguity>; + fn next(&mut self) -> Option { + match self.all_list_heads() { + ListHead::Cons(mut iter) => { + let (elem, rest) = iter.next().unwrap(); + let original = *self; + *self = rest; + if iter.next().is_none() { + Some(Ok(elem)) + } else { + match self.node.kind.shape() { + ParseNodeShape::Opt(_) => { + self.node.range = Range(original.node.range.split_at(0).0); + } + _ => unreachable!(), + } + match self.one_list_head() { + ListHead::Nil => {} + _ => unreachable!(), + } + Some(Err(Ambiguity(original))) + } + } + ListHead::Nil => None, + } + } +} + +pub enum ListHead { + Cons(C), + Nil, +} + +impl<'a, 'i, I: ::gll::runtime::Input, T> Handle<'a, 'i, I, [T]> { + fn one_list_head(self) -> ListHead, Handle<'a, 'i, I, [T]>), Ambiguity>> { + match self.all_list_heads() { + ListHead::Cons(mut iter) => { + let first = iter.next().unwrap(); + if iter.next().is_none() { + ListHead::Cons(Ok(first)) + } else { + ListHead::Cons(Err(Ambiguity(self))) + } + } + ListHead::Nil => ListHead::Nil, + } + } + fn all_list_heads(mut self) -> ListHead, Handle<'a, 'i, I, [T]>)>> { + if let ParseNodeShape::Opt(_) = self.node.kind.shape() { + if let Some(opt_child) = self.node.unpack_opt() { + self.node = opt_child; + } else { + return ListHead::Nil; + } + } + ListHead::Cons(self.parser.sppf.all_splits(self.node).flat_map(move |(elem, rest)| { + if let ParseNodeShape::Split(..) = rest.kind.shape() { + Some(self.parser.sppf.all_splits(rest)).into_iter().flatten().chain(None) + } else { + None.into_iter().flatten().chain(Some((elem, rest))) + } + }).map(move |(elem, rest)| { + (Handle { + node: elem, + parser: self.parser, + _marker: PhantomData, + }, Handle { node: rest, ..self }) + })) + } +} +macro_rules! P {(&[::gll::proc_macro::FlatTokenPat::Delim('('),]) => (_P::_0);(&[::gll::proc_macro::FlatTokenPat::Delim(')'),]) => (_P::_1);(&[::gll::proc_macro::FlatTokenPat::Delim('['),]) => (_P::_2);(&[::gll::proc_macro::FlatTokenPat::Delim(']'),]) => (_P::_3);(&[::gll::proc_macro::FlatTokenPat::Delim('{'),]) => (_P::_4);(&[::gll::proc_macro::FlatTokenPat::Delim('}'),]) => (_P::_5);(&[::gll::proc_macro::FlatTokenPat::Ident(None),]) => (_P::_6);(&[::gll::proc_macro::FlatTokenPat::Ident(Some("as")),]) => (_P::_7);(&[::gll::proc_macro::FlatTokenPat::Ident(Some("box")),]) => (_P::_8);(&[::gll::proc_macro::FlatTokenPat::Ident(Some("break")),]) => (_P::_9);(&[::gll::proc_macro::FlatTokenPat::Ident(Some("continue")),]) => (_P::_10);(&[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),]) => (_P::_11);(&[::gll::proc_macro::FlatTokenPat::Ident(Some("return")),]) => (_P::_12);(&[::gll::proc_macro::FlatTokenPat::Literal,]) => (_P::_13);(&[::gll::proc_macro::FlatTokenPat::Punct { ch: None, joint: None },]) => (_P::_14);(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('&'), joint: None },]) => (_P::_15);(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]) => (_P::_16);(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) => (_P::_17);(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) => (_P::_18);(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('='), joint: None },]) => (_P::_19);(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },]) => (_P::_20);(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('?'), joint: None },]) => (_P::_21);((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))) => (_P::_22);((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (TOKEN_TREE*))) => (_P::_23);((&[::gll::proc_macro::FlatTokenPat::Delim('('),] Expr)) => (_P::_24);((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))) => (_P::_25);((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (TOKEN_TREE*))) => (_P::_26);((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr)) => (_P::_27);((&[::gll::proc_macro::FlatTokenPat::Delim('{'),] (TOKEN_TREE*))) => (_P::_28);((&[::gll::proc_macro::FlatTokenPat::Ident(Some("box")),] Expr)) => (_P::_29);((&[::gll::proc_macro::FlatTokenPat::Ident(Some("break")),] (Expr?))) => (_P::_30);((&[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),]?)) => (_P::_31);((&[::gll::proc_macro::FlatTokenPat::Ident(Some("return")),] (Expr?))) => (_P::_32);((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('&'), joint: None },] (&[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),]?))) => (_P::_33);((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },] (Expr+ % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))) => (_P::_34);((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) => (_P::_35);(((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?))) => (_P::_36);(((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (TOKEN_TREE*)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => (_P::_37);(((&[::gll::proc_macro::FlatTokenPat::Delim('('),] Expr) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => (_P::_38);(((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?))) => (_P::_39);(((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (TOKEN_TREE*)) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])) => (_P::_40);(((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },])) => (_P::_41);(((&[::gll::proc_macro::FlatTokenPat::Delim('{'),] (TOKEN_TREE*)) &[::gll::proc_macro::FlatTokenPat::Delim('}'),])) => (_P::_42);(((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('&'), joint: None },] (&[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),]?)) Expr)) => (_P::_43);(((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },] (Expr+ % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))?)) => (_P::_44);((((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => (_P::_45);((((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])) => (_P::_46);((((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },]) Expr)) => (_P::_47);(((((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])) => (_P::_48);(((((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => (_P::_49);((((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?))) => (_P::_50);(((((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => (_P::_51);(((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))) => (_P::_52);((((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?))) => (_P::_53);((((Expr &[::gll::proc_macro::FlatTokenPat::Delim('['),]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])) => (_P::_54);((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),])) => (_P::_55);((((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) (Expr?))) => (_P::_56);((((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('='), joint: None },]) Expr)) => (_P::_57);(((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))) => (_P::_58);(((Expr &[::gll::proc_macro::FlatTokenPat::Delim('['),]) Expr)) => (_P::_59);(((Expr &[::gll::proc_macro::FlatTokenPat::Ident(Some("as")),]) IDENT)) => (_P::_60);(((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT)) => (_P::_61);(((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },])) => (_P::_62);(((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('='), joint: None },])) => (_P::_63);((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),])) => (_P::_64);((Expr &[::gll::proc_macro::FlatTokenPat::Delim('['),])) => (_P::_65);((Expr &[::gll::proc_macro::FlatTokenPat::Ident(Some("as")),])) => (_P::_66);((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },])) => (_P::_67);((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('?'), joint: None },])) => (_P::_68);((Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) => (_P::_69);((Expr*)) => (_P::_70);((Expr+ % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) => (_P::_71);((Expr+ HACK)) => (_P::_72);((Expr?)) => (_P::_73);((LITERAL | ((&[::gll::proc_macro::FlatTokenPat::Delim('('),] Expr) &[::gll::proc_macro::FlatTokenPat::Delim(')'),]) | ((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('&'), joint: None },] (&[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),]?)) Expr) | (&[::gll::proc_macro::FlatTokenPat::Ident(Some("box")),] Expr) | (Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('?'), joint: None },]) | (((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) (Expr?)) | (((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('='), joint: None },]) Expr) | ((Expr &[::gll::proc_macro::FlatTokenPat::Ident(Some("as")),]) IDENT) | (((Expr &[::gll::proc_macro::FlatTokenPat::Delim('['),]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(']'),]) | (((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(']'),]) | ((((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(']'),]) | (((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),]) | ((((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),]) | ((((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),]) | &[::gll::proc_macro::FlatTokenPat::Ident(Some("continue")),] | (&[::gll::proc_macro::FlatTokenPat::Ident(Some("break")),] (Expr?)) | (&[::gll::proc_macro::FlatTokenPat::Ident(Some("return")),] (Expr?)))) => (_P::_74);((TOKEN_TREE*)) => (_P::_75);((TOKEN_TREE+ HACK)) => (_P::_76);(Expr) => (_P::_77);(IDENT) => (_P::_78);(LIFETIME) => (_P::_79);(LITERAL) => (_P::_80);(ModuleContents) => (_P::_81);(PUNCT) => (_P::_82);(TOKEN_TREE) => (_P::_83);}#[allow(non_camel_case_types)]pub struct IDENT<'a, 'i: 'a, I: 'a + ::gll::runtime::Input> {_marker: PhantomData<(&'a (), &'i (), I)>,}impl<'a, 'i, I: ::gll::runtime::Input> fmt::Debug for IDENT<'a, 'i, I> {fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {let mut d = f.debug_struct("IDENT");d.finish()}} + impl<'a, 'i, I: ::gll::runtime::Input> fmt::Debug for Handle<'a, 'i, I, IDENT<'a, 'i, I>> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self.source_info()) + } + } + impl<'a, 'i, I: ::gll::runtime::Input> IDENT<'a, 'i, I> { + fn from_sppf( + parser: &'a ::gll::runtime::Parser<'i, _P, _C, I>, + _node: ParseNode<'i, _P>, + _r: traverse!(typeof(ParseNode<'i, _P>) _), + ) -> Self {IDENT{_marker: PhantomData,}}}impl<'a, 'i, I: ::gll::runtime::Input> Handle<'a, 'i, I, IDENT<'a, 'i, I>> {pub fn one(self) -> Result, Ambiguity> { + // HACK(eddyb) using a closure to catch `Err`s from `?` + (|| Ok({ + #[allow(unused_variables)] + let sppf = &self.parser.sppf; + let node = self.node.unpack_alias(); + let r = traverse!(one(sppf, node) _); + IDENT::from_sppf(self.parser, node, r) + }))().map_err(|::gll::runtime::MoreThanOne| Ambiguity(self)) + }pub fn all(self) -> impl Iterator> { + #[allow(unused_variables)] + let sppf = &self.parser.sppf; + let node = self.node.unpack_alias(); + traverse!(all(sppf) _) + .apply(node) + .map(move |r| IDENT::from_sppf(self.parser, node, r))}} + impl<'a, 'i, I: ::gll::runtime::Input> IDENT<'a, 'i, I> { + pub fn parse_with( + input: I, + f: impl for<'b, 'i2> FnOnce( + &'b ::gll::runtime::Parser<'i2, _P, _C, I>, + ParseResult<'b, 'i2, I, IDENT<'b, 'i2, I>>, + ) -> R, + ) -> R { + ::gll::runtime::Parser::with(input, |mut parser, range| { + let call = Call { + callee: _C::IDENT, + range, + }; + parser.threads.spawn( + Continuation { + code: call.callee, + fn_input: call.range, + state: 0, + }, + call.range, + ); + parse(&mut parser); + let result = parser.memoizer.longest_result(call); + f(&parser, result.ok_or(ParseError::NoParse).and_then(|range| { + let handle = Handle { + node: ParseNode { kind: P!(IDENT), range }, + parser: &parser, + _marker: PhantomData, + }; + if range == call.range { + Ok(handle) + } else { + Err(ParseError::TooShort(handle)) + } + })) + }) + } + }#[allow(non_camel_case_types)]pub struct PUNCT<'a, 'i: 'a, I: 'a + ::gll::runtime::Input> {_marker: PhantomData<(&'a (), &'i (), I)>,}impl<'a, 'i, I: ::gll::runtime::Input> fmt::Debug for PUNCT<'a, 'i, I> {fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {let mut d = f.debug_struct("PUNCT");d.finish()}} + impl<'a, 'i, I: ::gll::runtime::Input> fmt::Debug for Handle<'a, 'i, I, PUNCT<'a, 'i, I>> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self.source_info()) + } + } + impl<'a, 'i, I: ::gll::runtime::Input> PUNCT<'a, 'i, I> { + fn from_sppf( + parser: &'a ::gll::runtime::Parser<'i, _P, _C, I>, + _node: ParseNode<'i, _P>, + _r: traverse!(typeof(ParseNode<'i, _P>) _), + ) -> Self {PUNCT{_marker: PhantomData,}}}impl<'a, 'i, I: ::gll::runtime::Input> Handle<'a, 'i, I, PUNCT<'a, 'i, I>> {pub fn one(self) -> Result, Ambiguity> { + // HACK(eddyb) using a closure to catch `Err`s from `?` + (|| Ok({ + #[allow(unused_variables)] + let sppf = &self.parser.sppf; + let node = self.node.unpack_alias(); + let r = traverse!(one(sppf, node) _); + PUNCT::from_sppf(self.parser, node, r) + }))().map_err(|::gll::runtime::MoreThanOne| Ambiguity(self)) + }pub fn all(self) -> impl Iterator> { + #[allow(unused_variables)] + let sppf = &self.parser.sppf; + let node = self.node.unpack_alias(); + traverse!(all(sppf) _) + .apply(node) + .map(move |r| PUNCT::from_sppf(self.parser, node, r))}} + impl<'a, 'i, I: ::gll::runtime::Input> PUNCT<'a, 'i, I> { + pub fn parse_with( + input: I, + f: impl for<'b, 'i2> FnOnce( + &'b ::gll::runtime::Parser<'i2, _P, _C, I>, + ParseResult<'b, 'i2, I, PUNCT<'b, 'i2, I>>, + ) -> R, + ) -> R { + ::gll::runtime::Parser::with(input, |mut parser, range| { + let call = Call { + callee: _C::PUNCT, + range, + }; + parser.threads.spawn( + Continuation { + code: call.callee, + fn_input: call.range, + state: 0, + }, + call.range, + ); + parse(&mut parser); + let result = parser.memoizer.longest_result(call); + f(&parser, result.ok_or(ParseError::NoParse).and_then(|range| { + let handle = Handle { + node: ParseNode { kind: P!(PUNCT), range }, + parser: &parser, + _marker: PhantomData, + }; + if range == call.range { + Ok(handle) + } else { + Err(ParseError::TooShort(handle)) + } + })) + }) + } + }#[allow(non_camel_case_types)]pub struct LITERAL<'a, 'i: 'a, I: 'a + ::gll::runtime::Input> {_marker: PhantomData<(&'a (), &'i (), I)>,}impl<'a, 'i, I: ::gll::runtime::Input> fmt::Debug for LITERAL<'a, 'i, I> {fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {let mut d = f.debug_struct("LITERAL");d.finish()}} + impl<'a, 'i, I: ::gll::runtime::Input> fmt::Debug for Handle<'a, 'i, I, LITERAL<'a, 'i, I>> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self.source_info()) + } + } + impl<'a, 'i, I: ::gll::runtime::Input> LITERAL<'a, 'i, I> { + fn from_sppf( + parser: &'a ::gll::runtime::Parser<'i, _P, _C, I>, + _node: ParseNode<'i, _P>, + _r: traverse!(typeof(ParseNode<'i, _P>) _), + ) -> Self {LITERAL{_marker: PhantomData,}}}impl<'a, 'i, I: ::gll::runtime::Input> Handle<'a, 'i, I, LITERAL<'a, 'i, I>> {pub fn one(self) -> Result, Ambiguity> { + // HACK(eddyb) using a closure to catch `Err`s from `?` + (|| Ok({ + #[allow(unused_variables)] + let sppf = &self.parser.sppf; + let node = self.node.unpack_alias(); + let r = traverse!(one(sppf, node) _); + LITERAL::from_sppf(self.parser, node, r) + }))().map_err(|::gll::runtime::MoreThanOne| Ambiguity(self)) + }pub fn all(self) -> impl Iterator> { + #[allow(unused_variables)] + let sppf = &self.parser.sppf; + let node = self.node.unpack_alias(); + traverse!(all(sppf) _) + .apply(node) + .map(move |r| LITERAL::from_sppf(self.parser, node, r))}} + impl<'a, 'i, I: ::gll::runtime::Input> LITERAL<'a, 'i, I> { + pub fn parse_with( + input: I, + f: impl for<'b, 'i2> FnOnce( + &'b ::gll::runtime::Parser<'i2, _P, _C, I>, + ParseResult<'b, 'i2, I, LITERAL<'b, 'i2, I>>, + ) -> R, + ) -> R { + ::gll::runtime::Parser::with(input, |mut parser, range| { + let call = Call { + callee: _C::LITERAL, + range, + }; + parser.threads.spawn( + Continuation { + code: call.callee, + fn_input: call.range, + state: 0, + }, + call.range, + ); + parse(&mut parser); + let result = parser.memoizer.longest_result(call); + f(&parser, result.ok_or(ParseError::NoParse).and_then(|range| { + let handle = Handle { + node: ParseNode { kind: P!(LITERAL), range }, + parser: &parser, + _marker: PhantomData, + }; + if range == call.range { + Ok(handle) + } else { + Err(ParseError::TooShort(handle)) + } + })) + }) + } + }#[allow(non_camel_case_types)]pub struct TOKEN_TREE<'a, 'i: 'a, I: 'a + ::gll::runtime::Input> {_marker: PhantomData<(&'a (), &'i (), I)>,}impl<'a, 'i, I: ::gll::runtime::Input> fmt::Debug for TOKEN_TREE<'a, 'i, I> {fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {let mut d = f.debug_struct("TOKEN_TREE");d.finish()}} + impl<'a, 'i, I: ::gll::runtime::Input> fmt::Debug for Handle<'a, 'i, I, TOKEN_TREE<'a, 'i, I>> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self.source_info()) + } + } + impl<'a, 'i, I: ::gll::runtime::Input> TOKEN_TREE<'a, 'i, I> { + fn from_sppf( + parser: &'a ::gll::runtime::Parser<'i, _P, _C, I>, + _node: ParseNode<'i, _P>, + _r: traverse!(typeof(ParseNode<'i, _P>) { 0 _0: P!(&[::gll::proc_macro::FlatTokenPat::Ident(None),]) => ?,1 _1: P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: None, joint: None },]) => ?,2 _2: P!(&[::gll::proc_macro::FlatTokenPat::Literal,]) => ?,3 _3: P!(((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (TOKEN_TREE*)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => ((?, ?), ?),4 _4: P!(((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (TOKEN_TREE*)) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])) => ((?, ?), ?),5 _5: P!(((&[::gll::proc_macro::FlatTokenPat::Delim('{'),] (TOKEN_TREE*)) &[::gll::proc_macro::FlatTokenPat::Delim('}'),])) => ((?, ?), ?), }), + ) -> Self {TOKEN_TREE{_marker: PhantomData,}}}impl<'a, 'i, I: ::gll::runtime::Input> Handle<'a, 'i, I, TOKEN_TREE<'a, 'i, I>> {pub fn one(self) -> Result, Ambiguity> { + // HACK(eddyb) using a closure to catch `Err`s from `?` + (|| Ok({ + #[allow(unused_variables)] + let sppf = &self.parser.sppf; + let node = self.node.unpack_alias(); + let r = traverse!(one(sppf, node) { 0 _0: P!(&[::gll::proc_macro::FlatTokenPat::Ident(None),]) => ?,1 _1: P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: None, joint: None },]) => ?,2 _2: P!(&[::gll::proc_macro::FlatTokenPat::Literal,]) => ?,3 _3: P!(((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (TOKEN_TREE*)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => ((?, ?), ?),4 _4: P!(((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (TOKEN_TREE*)) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])) => ((?, ?), ?),5 _5: P!(((&[::gll::proc_macro::FlatTokenPat::Delim('{'),] (TOKEN_TREE*)) &[::gll::proc_macro::FlatTokenPat::Delim('}'),])) => ((?, ?), ?), }); + TOKEN_TREE::from_sppf(self.parser, node, r) + }))().map_err(|::gll::runtime::MoreThanOne| Ambiguity(self)) + }pub fn all(self) -> impl Iterator> { + #[allow(unused_variables)] + let sppf = &self.parser.sppf; + let node = self.node.unpack_alias(); + traverse!(all(sppf) { 0 _0: P!(&[::gll::proc_macro::FlatTokenPat::Ident(None),]) => ?,1 _1: P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: None, joint: None },]) => ?,2 _2: P!(&[::gll::proc_macro::FlatTokenPat::Literal,]) => ?,3 _3: P!(((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (TOKEN_TREE*)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => ((?, ?), ?),4 _4: P!(((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (TOKEN_TREE*)) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])) => ((?, ?), ?),5 _5: P!(((&[::gll::proc_macro::FlatTokenPat::Delim('{'),] (TOKEN_TREE*)) &[::gll::proc_macro::FlatTokenPat::Delim('}'),])) => ((?, ?), ?), }) + .apply(node) + .map(move |r| TOKEN_TREE::from_sppf(self.parser, node, r))}} + impl<'a, 'i, I: ::gll::runtime::Input> TOKEN_TREE<'a, 'i, I> { + pub fn parse_with( + input: I, + f: impl for<'b, 'i2> FnOnce( + &'b ::gll::runtime::Parser<'i2, _P, _C, I>, + ParseResult<'b, 'i2, I, TOKEN_TREE<'b, 'i2, I>>, + ) -> R, + ) -> R { + ::gll::runtime::Parser::with(input, |mut parser, range| { + let call = Call { + callee: _C::TOKEN_TREE, + range, + }; + parser.threads.spawn( + Continuation { + code: call.callee, + fn_input: call.range, + state: 0, + }, + call.range, + ); + parse(&mut parser); + let result = parser.memoizer.longest_result(call); + f(&parser, result.ok_or(ParseError::NoParse).and_then(|range| { + let handle = Handle { + node: ParseNode { kind: P!(TOKEN_TREE), range }, + parser: &parser, + _marker: PhantomData, + }; + if range == call.range { + Ok(handle) + } else { + Err(ParseError::TooShort(handle)) + } + })) + }) + } + }#[allow(non_camel_case_types)]pub struct LIFETIME<'a, 'i: 'a, I: 'a + ::gll::runtime::Input> {_marker: PhantomData<(&'a (), &'i (), I)>,}impl<'a, 'i, I: ::gll::runtime::Input> fmt::Debug for LIFETIME<'a, 'i, I> {fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {let mut d = f.debug_struct("LIFETIME");d.finish()}} + impl<'a, 'i, I: ::gll::runtime::Input> fmt::Debug for Handle<'a, 'i, I, LIFETIME<'a, 'i, I>> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self.source_info()) + } + } + impl<'a, 'i, I: ::gll::runtime::Input> LIFETIME<'a, 'i, I> { + fn from_sppf( + parser: &'a ::gll::runtime::Parser<'i, _P, _C, I>, + _node: ParseNode<'i, _P>, + _r: traverse!(typeof(ParseNode<'i, _P>) _), + ) -> Self {LIFETIME{_marker: PhantomData,}}}impl<'a, 'i, I: ::gll::runtime::Input> Handle<'a, 'i, I, LIFETIME<'a, 'i, I>> {pub fn one(self) -> Result, Ambiguity> { + // HACK(eddyb) using a closure to catch `Err`s from `?` + (|| Ok({ + #[allow(unused_variables)] + let sppf = &self.parser.sppf; + let node = self.node.unpack_alias(); + let r = traverse!(one(sppf, node) _); + LIFETIME::from_sppf(self.parser, node, r) + }))().map_err(|::gll::runtime::MoreThanOne| Ambiguity(self)) + }pub fn all(self) -> impl Iterator> { + #[allow(unused_variables)] + let sppf = &self.parser.sppf; + let node = self.node.unpack_alias(); + traverse!(all(sppf) _) + .apply(node) + .map(move |r| LIFETIME::from_sppf(self.parser, node, r))}} + impl<'a, 'i, I: ::gll::runtime::Input> LIFETIME<'a, 'i, I> { + pub fn parse_with( + input: I, + f: impl for<'b, 'i2> FnOnce( + &'b ::gll::runtime::Parser<'i2, _P, _C, I>, + ParseResult<'b, 'i2, I, LIFETIME<'b, 'i2, I>>, + ) -> R, + ) -> R { + ::gll::runtime::Parser::with(input, |mut parser, range| { + let call = Call { + callee: _C::LIFETIME, + range, + }; + parser.threads.spawn( + Continuation { + code: call.callee, + fn_input: call.range, + state: 0, + }, + call.range, + ); + parse(&mut parser); + let result = parser.memoizer.longest_result(call); + f(&parser, result.ok_or(ParseError::NoParse).and_then(|range| { + let handle = Handle { + node: ParseNode { kind: P!(LIFETIME), range }, + parser: &parser, + _marker: PhantomData, + }; + if range == call.range { + Ok(handle) + } else { + Err(ParseError::TooShort(handle)) + } + })) + }) + } + }pub enum Expr<'a, 'i: 'a, I: 'a + ::gll::runtime::Input> {Literal(Handle<'a, 'i, I, LITERAL<'a, 'i, I>>),Paren {expr: Handle<'a, 'i, I, Expr<'a, 'i, I>>,},Borrow {expr: Handle<'a, 'i, I, Expr<'a, 'i, I>>,mutable: Option>,},Box {expr: Handle<'a, 'i, I, Expr<'a, 'i, I>>,},Try {expr: Handle<'a, 'i, I, Expr<'a, 'i, I>>,},Range {start: Option>>,end: Option>>,},RangeInclusive {start: Option>>,end: Handle<'a, 'i, I, Expr<'a, 'i, I>>,},Cast {expr: Handle<'a, 'i, I, Expr<'a, 'i, I>>,ty: Handle<'a, 'i, I, IDENT<'a, 'i, I>>,},Index {base: Handle<'a, 'i, I, Expr<'a, 'i, I>>,index: Handle<'a, 'i, I, Expr<'a, 'i, I>>,},Array {exprs: Handle<'a, 'i, I, [Expr<'a, 'i, I>]>,},Repeat {elem: Handle<'a, 'i, I, Expr<'a, 'i, I>>,count: Handle<'a, 'i, I, Expr<'a, 'i, I>>,},Tuple {exprs: Handle<'a, 'i, I, [Expr<'a, 'i, I>]>,},Call {callee: Handle<'a, 'i, I, Expr<'a, 'i, I>>,args: Handle<'a, 'i, I, [Expr<'a, 'i, I>]>,},MethodCall {args: Handle<'a, 'i, I, [Expr<'a, 'i, I>]>,receiver: Handle<'a, 'i, I, Expr<'a, 'i, I>>,method: Handle<'a, 'i, I, IDENT<'a, 'i, I>>,},Continue(Handle<'a, 'i, I, ()>),Break {value: Option>>,},Return {value: Option>>,},}impl<'a, 'i, I: ::gll::runtime::Input> fmt::Debug for Expr<'a, 'i, I> {fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {match self {Expr::Literal(x) => f.debug_tuple("Expr::Literal").field(x).finish(),Expr::Paren { expr: f_expr, } => {let mut d = f.debug_struct("Expr::Paren");d.field("expr", f_expr);d.finish()}Expr::Borrow { expr: f_expr, mutable: f_mutable, } => {let mut d = f.debug_struct("Expr::Borrow");d.field("expr", f_expr);if let Some(field) = f_mutable { d.field("mutable", field); }d.finish()}Expr::Box { expr: f_expr, } => {let mut d = f.debug_struct("Expr::Box");d.field("expr", f_expr);d.finish()}Expr::Try { expr: f_expr, } => {let mut d = f.debug_struct("Expr::Try");d.field("expr", f_expr);d.finish()}Expr::Range { start: f_start, end: f_end, } => {let mut d = f.debug_struct("Expr::Range");if let Some(field) = f_start { d.field("start", field); }if let Some(field) = f_end { d.field("end", field); }d.finish()}Expr::RangeInclusive { start: f_start, end: f_end, } => {let mut d = f.debug_struct("Expr::RangeInclusive");if let Some(field) = f_start { d.field("start", field); }d.field("end", f_end);d.finish()}Expr::Cast { expr: f_expr, ty: f_ty, } => {let mut d = f.debug_struct("Expr::Cast");d.field("expr", f_expr);d.field("ty", f_ty);d.finish()}Expr::Index { base: f_base, index: f_index, } => {let mut d = f.debug_struct("Expr::Index");d.field("base", f_base);d.field("index", f_index);d.finish()}Expr::Array { exprs: f_exprs, } => {let mut d = f.debug_struct("Expr::Array");d.field("exprs", f_exprs);d.finish()}Expr::Repeat { elem: f_elem, count: f_count, } => {let mut d = f.debug_struct("Expr::Repeat");d.field("elem", f_elem);d.field("count", f_count);d.finish()}Expr::Tuple { exprs: f_exprs, } => {let mut d = f.debug_struct("Expr::Tuple");d.field("exprs", f_exprs);d.finish()}Expr::Call { callee: f_callee, args: f_args, } => {let mut d = f.debug_struct("Expr::Call");d.field("callee", f_callee);d.field("args", f_args);d.finish()}Expr::MethodCall { args: f_args, receiver: f_receiver, method: f_method, } => {let mut d = f.debug_struct("Expr::MethodCall");d.field("args", f_args);d.field("receiver", f_receiver);d.field("method", f_method);d.finish()}Expr::Continue(x) => f.debug_tuple("Expr::Continue").field(x).finish(),Expr::Break { value: f_value, } => {let mut d = f.debug_struct("Expr::Break");if let Some(field) = f_value { d.field("value", field); }d.finish()}Expr::Return { value: f_value, } => {let mut d = f.debug_struct("Expr::Return");if let Some(field) = f_value { d.field("value", field); }d.finish()}}}} + impl<'a, 'i, I: ::gll::runtime::Input> fmt::Debug for Handle<'a, 'i, I, Expr<'a, 'i, I>> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?} => ", self.source_info())?; + let mut first = true; + for x in self.all() { + if !first { + write!(f, " | ")?; + } + first = false; + fmt::Debug::fmt(&x, f)?; + } + Ok(()) + } + } + impl<'a, 'i, I: ::gll::runtime::Input> Expr<'a, 'i, I> { + #[allow(non_snake_case)] + fn Literal_from_sppf( + parser: &'a ::gll::runtime::Parser<'i, _P, _C, I>, + _node: ParseNode<'i, _P>, + _r: traverse!(typeof(ParseNode<'i, _P>) _), + ) -> Self {Expr::Literal(Handle { node: _node, parser, _marker: PhantomData, })} + #[allow(non_snake_case)] + fn Paren_from_sppf( + parser: &'a ::gll::runtime::Parser<'i, _P, _C, I>, + _node: ParseNode<'i, _P>, + _r: traverse!(typeof(ParseNode<'i, _P>) ((_, _), _)), + ) -> Self {Expr::Paren {expr: Handle { node: _r .0 .1, parser, _marker: PhantomData, },}} + #[allow(non_snake_case)] + fn Borrow_from_sppf( + parser: &'a ::gll::runtime::Parser<'i, _P, _C, I>, + _node: ParseNode<'i, _P>, + _r: traverse!(typeof(ParseNode<'i, _P>) ((_, [?]), _)), + ) -> Self {Expr::Borrow {expr: Handle { node: _r .1, parser, _marker: PhantomData, },mutable: None.or(_r .0 .1 .0).map(|node| Handle { + node, + parser, + _marker: PhantomData, + }),}} + #[allow(non_snake_case)] + fn Box_from_sppf( + parser: &'a ::gll::runtime::Parser<'i, _P, _C, I>, + _node: ParseNode<'i, _P>, + _r: traverse!(typeof(ParseNode<'i, _P>) (_, _)), + ) -> Self {Expr::Box {expr: Handle { node: _r .1, parser, _marker: PhantomData, },}} + #[allow(non_snake_case)] + fn Try_from_sppf( + parser: &'a ::gll::runtime::Parser<'i, _P, _C, I>, + _node: ParseNode<'i, _P>, + _r: traverse!(typeof(ParseNode<'i, _P>) (_, _)), + ) -> Self {Expr::Try {expr: Handle { node: _r .0, parser, _marker: PhantomData, },}} + #[allow(non_snake_case)] + fn Range_from_sppf( + parser: &'a ::gll::runtime::Parser<'i, _P, _C, I>, + _node: ParseNode<'i, _P>, + _r: traverse!(typeof(ParseNode<'i, _P>) (([?], _), [?])), + ) -> Self {Expr::Range {start: None.or(_r .0 .0 .0).map(|node| Handle { + node, + parser, + _marker: PhantomData, + }),end: None.or(_r .1 .0).map(|node| Handle { + node, + parser, + _marker: PhantomData, + }),}} + #[allow(non_snake_case)] + fn RangeInclusive_from_sppf( + parser: &'a ::gll::runtime::Parser<'i, _P, _C, I>, + _node: ParseNode<'i, _P>, + _r: traverse!(typeof(ParseNode<'i, _P>) (([?], _), _)), + ) -> Self {Expr::RangeInclusive {start: None.or(_r .0 .0 .0).map(|node| Handle { + node, + parser, + _marker: PhantomData, + }),end: Handle { node: _r .1, parser, _marker: PhantomData, },}} + #[allow(non_snake_case)] + fn Cast_from_sppf( + parser: &'a ::gll::runtime::Parser<'i, _P, _C, I>, + _node: ParseNode<'i, _P>, + _r: traverse!(typeof(ParseNode<'i, _P>) ((_, _), _)), + ) -> Self {Expr::Cast {expr: Handle { node: _r .0 .0, parser, _marker: PhantomData, },ty: Handle { node: _r .1, parser, _marker: PhantomData, },}} + #[allow(non_snake_case)] + fn Index_from_sppf( + parser: &'a ::gll::runtime::Parser<'i, _P, _C, I>, + _node: ParseNode<'i, _P>, + _r: traverse!(typeof(ParseNode<'i, _P>) (((_, _), _), _)), + ) -> Self {Expr::Index {base: Handle { node: _r .0 .0 .0, parser, _marker: PhantomData, },index: Handle { node: _r .0 .1, parser, _marker: PhantomData, },}} + #[allow(non_snake_case)] + fn Array_from_sppf( + parser: &'a ::gll::runtime::Parser<'i, _P, _C, I>, + _node: ParseNode<'i, _P>, + _r: traverse!(typeof(ParseNode<'i, _P>) (((_, _), [?]), _)), + ) -> Self {Expr::Array {exprs: Handle { node: _r .0 .0 .1, parser, _marker: PhantomData, },}} + #[allow(non_snake_case)] + fn Repeat_from_sppf( + parser: &'a ::gll::runtime::Parser<'i, _P, _C, I>, + _node: ParseNode<'i, _P>, + _r: traverse!(typeof(ParseNode<'i, _P>) ((((_, _), _), _), _)), + ) -> Self {Expr::Repeat {elem: Handle { node: _r .0 .0 .0 .1, parser, _marker: PhantomData, },count: Handle { node: _r .0 .1, parser, _marker: PhantomData, },}} + #[allow(non_snake_case)] + fn Tuple_from_sppf( + parser: &'a ::gll::runtime::Parser<'i, _P, _C, I>, + _node: ParseNode<'i, _P>, + _r: traverse!(typeof(ParseNode<'i, _P>) (((_, _), [?]), _)), + ) -> Self {Expr::Tuple {exprs: Handle { node: _r .0 .0 .1, parser, _marker: PhantomData, },}} + #[allow(non_snake_case)] + fn Call_from_sppf( + parser: &'a ::gll::runtime::Parser<'i, _P, _C, I>, + _node: ParseNode<'i, _P>, + _r: traverse!(typeof(ParseNode<'i, _P>) ((((_, _), _), [?]), _)), + ) -> Self {Expr::Call {callee: Handle { node: _r .0 .0 .0 .0, parser, _marker: PhantomData, },args: Handle { node: _r .0 .0 .1, parser, _marker: PhantomData, },}} + #[allow(non_snake_case)] + fn MethodCall_from_sppf( + parser: &'a ::gll::runtime::Parser<'i, _P, _C, I>, + _node: ParseNode<'i, _P>, + _r: traverse!(typeof(ParseNode<'i, _P>) ((((((_, _), _), _), _), [?]), _)), + ) -> Self {Expr::MethodCall {args: Handle { node: _r .0 .0 .1, parser, _marker: PhantomData, },receiver: Handle { node: _r .0 .0 .0 .0 .0 .0, parser, _marker: PhantomData, },method: Handle { node: _r .0 .0 .0 .0 .1, parser, _marker: PhantomData, },}} + #[allow(non_snake_case)] + fn Continue_from_sppf( + parser: &'a ::gll::runtime::Parser<'i, _P, _C, I>, + _node: ParseNode<'i, _P>, + _r: traverse!(typeof(ParseNode<'i, _P>) _), + ) -> Self {Expr::Continue(Handle { node: _node, parser, _marker: PhantomData, })} + #[allow(non_snake_case)] + fn Break_from_sppf( + parser: &'a ::gll::runtime::Parser<'i, _P, _C, I>, + _node: ParseNode<'i, _P>, + _r: traverse!(typeof(ParseNode<'i, _P>) (_, [?])), + ) -> Self {Expr::Break {value: None.or(_r .1 .0).map(|node| Handle { + node, + parser, + _marker: PhantomData, + }),}} + #[allow(non_snake_case)] + fn Return_from_sppf( + parser: &'a ::gll::runtime::Parser<'i, _P, _C, I>, + _node: ParseNode<'i, _P>, + _r: traverse!(typeof(ParseNode<'i, _P>) (_, [?])), + ) -> Self {Expr::Return {value: None.or(_r .1 .0).map(|node| Handle { + node, + parser, + _marker: PhantomData, + }),}}}impl<'a, 'i, I: ::gll::runtime::Input> Handle<'a, 'i, I, Expr<'a, 'i, I>> {pub fn one(self) -> Result, Ambiguity> { + // HACK(eddyb) using a closure to catch `Err`s from `?` + (|| Ok({ + #[allow(unused_variables)] + let sppf = &self.parser.sppf; + let node = self.node.unpack_alias(); + let node = sppf.one_choice(node)?; + match node.kind {P!(LITERAL) => { + let r = traverse!(one(sppf, node) _);Expr::Literal_from_sppf(self.parser, node, r) + }P!(((&[::gll::proc_macro::FlatTokenPat::Delim('('),] Expr) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => { + let r = traverse!(one(sppf, node) ((_, _), _));Expr::Paren_from_sppf(self.parser, node, r) + }P!(((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('&'), joint: None },] (&[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),]?)) Expr)) => { + let r = traverse!(one(sppf, node) ((_, [?]), _));Expr::Borrow_from_sppf(self.parser, node, r) + }P!((&[::gll::proc_macro::FlatTokenPat::Ident(Some("box")),] Expr)) => { + let r = traverse!(one(sppf, node) (_, _));Expr::Box_from_sppf(self.parser, node, r) + }P!((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('?'), joint: None },])) => { + let r = traverse!(one(sppf, node) (_, _));Expr::Try_from_sppf(self.parser, node, r) + }P!((((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) (Expr?))) => { + let r = traverse!(one(sppf, node) (([?], _), [?]));Expr::Range_from_sppf(self.parser, node, r) + }P!((((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('='), joint: None },]) Expr)) => { + let r = traverse!(one(sppf, node) (([?], _), _));Expr::RangeInclusive_from_sppf(self.parser, node, r) + }P!(((Expr &[::gll::proc_macro::FlatTokenPat::Ident(Some("as")),]) IDENT)) => { + let r = traverse!(one(sppf, node) ((_, _), _));Expr::Cast_from_sppf(self.parser, node, r) + }P!((((Expr &[::gll::proc_macro::FlatTokenPat::Delim('['),]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])) => { + let r = traverse!(one(sppf, node) (((_, _), _), _));Expr::Index_from_sppf(self.parser, node, r) + }P!((((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])) => { + let r = traverse!(one(sppf, node) (((_, _), [?]), _));Expr::Array_from_sppf(self.parser, node, r) + }P!(((((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])) => { + let r = traverse!(one(sppf, node) ((((_, _), _), _), _));Expr::Repeat_from_sppf(self.parser, node, r) + }P!((((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => { + let r = traverse!(one(sppf, node) (((_, _), [?]), _));Expr::Tuple_from_sppf(self.parser, node, r) + }P!(((((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => { + let r = traverse!(one(sppf, node) ((((_, _), _), [?]), _));Expr::Call_from_sppf(self.parser, node, r) + }P!(((((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => { + let r = traverse!(one(sppf, node) ((((((_, _), _), _), _), [?]), _));Expr::MethodCall_from_sppf(self.parser, node, r) + }P!(&[::gll::proc_macro::FlatTokenPat::Ident(Some("continue")),]) => { + let r = traverse!(one(sppf, node) _);Expr::Continue_from_sppf(self.parser, node, r) + }P!((&[::gll::proc_macro::FlatTokenPat::Ident(Some("break")),] (Expr?))) => { + let r = traverse!(one(sppf, node) (_, [?]));Expr::Break_from_sppf(self.parser, node, r) + }P!((&[::gll::proc_macro::FlatTokenPat::Ident(Some("return")),] (Expr?))) => { + let r = traverse!(one(sppf, node) (_, [?]));Expr::Return_from_sppf(self.parser, node, r) + }_ => unreachable!()} + }))().map_err(|::gll::runtime::MoreThanOne| Ambiguity(self)) + }pub fn all(self) -> impl Iterator> { + #[allow(unused_variables)] + let sppf = &self.parser.sppf; + let node = self.node.unpack_alias();#[derive(Clone)] enum Iter<_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,> {_0(_0),_1(_1),_2(_2),_3(_3),_4(_4),_5(_5),_6(_6),_7(_7),_8(_8),_9(_9),_10(_10),_11(_11),_12(_12),_13(_13),_14(_14),_15(_15),_16(_16),}impl,_1: Iterator,_2: Iterator,_3: Iterator,_4: Iterator,_5: Iterator,_6: Iterator,_7: Iterator,_8: Iterator,_9: Iterator,_10: Iterator,_11: Iterator,_12: Iterator,_13: Iterator,_14: Iterator,_15: Iterator,_16: Iterator,> Iterator for Iter<_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,> + { + type Item = T; + fn next(&mut self) -> Option { + match self { + Iter::_0(iter) => iter.next(), + Iter::_1(iter) => iter.next(), + Iter::_2(iter) => iter.next(), + Iter::_3(iter) => iter.next(), + Iter::_4(iter) => iter.next(), + Iter::_5(iter) => iter.next(), + Iter::_6(iter) => iter.next(), + Iter::_7(iter) => iter.next(), + Iter::_8(iter) => iter.next(), + Iter::_9(iter) => iter.next(), + Iter::_10(iter) => iter.next(), + Iter::_11(iter) => iter.next(), + Iter::_12(iter) => iter.next(), + Iter::_13(iter) => iter.next(), + Iter::_14(iter) => iter.next(), + Iter::_15(iter) => iter.next(), + Iter::_16(iter) => iter.next(), + } + } + } + sppf.all_choices(node).flat_map(move |node| { + match node.kind { + P!(LITERAL) => Iter::_0( + traverse!(all(sppf) _) + .apply(node) + .map(move |r| Expr::Literal_from_sppf(self.parser, node, r)) + ), + P!(((&[::gll::proc_macro::FlatTokenPat::Delim('('),] Expr) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => Iter::_1( + traverse!(all(sppf) ((_, _), _)) + .apply(node) + .map(move |r| Expr::Paren_from_sppf(self.parser, node, r)) + ), + P!(((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('&'), joint: None },] (&[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),]?)) Expr)) => Iter::_2( + traverse!(all(sppf) ((_, [?]), _)) + .apply(node) + .map(move |r| Expr::Borrow_from_sppf(self.parser, node, r)) + ), + P!((&[::gll::proc_macro::FlatTokenPat::Ident(Some("box")),] Expr)) => Iter::_3( + traverse!(all(sppf) (_, _)) + .apply(node) + .map(move |r| Expr::Box_from_sppf(self.parser, node, r)) + ), + P!((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('?'), joint: None },])) => Iter::_4( + traverse!(all(sppf) (_, _)) + .apply(node) + .map(move |r| Expr::Try_from_sppf(self.parser, node, r)) + ), + P!((((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) (Expr?))) => Iter::_5( + traverse!(all(sppf) (([?], _), [?])) + .apply(node) + .map(move |r| Expr::Range_from_sppf(self.parser, node, r)) + ), + P!((((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('='), joint: None },]) Expr)) => Iter::_6( + traverse!(all(sppf) (([?], _), _)) + .apply(node) + .map(move |r| Expr::RangeInclusive_from_sppf(self.parser, node, r)) + ), + P!(((Expr &[::gll::proc_macro::FlatTokenPat::Ident(Some("as")),]) IDENT)) => Iter::_7( + traverse!(all(sppf) ((_, _), _)) + .apply(node) + .map(move |r| Expr::Cast_from_sppf(self.parser, node, r)) + ), + P!((((Expr &[::gll::proc_macro::FlatTokenPat::Delim('['),]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])) => Iter::_8( + traverse!(all(sppf) (((_, _), _), _)) + .apply(node) + .map(move |r| Expr::Index_from_sppf(self.parser, node, r)) + ), + P!((((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])) => Iter::_9( + traverse!(all(sppf) (((_, _), [?]), _)) + .apply(node) + .map(move |r| Expr::Array_from_sppf(self.parser, node, r)) + ), + P!(((((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])) => Iter::_10( + traverse!(all(sppf) ((((_, _), _), _), _)) + .apply(node) + .map(move |r| Expr::Repeat_from_sppf(self.parser, node, r)) + ), + P!((((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => Iter::_11( + traverse!(all(sppf) (((_, _), [?]), _)) + .apply(node) + .map(move |r| Expr::Tuple_from_sppf(self.parser, node, r)) + ), + P!(((((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => Iter::_12( + traverse!(all(sppf) ((((_, _), _), [?]), _)) + .apply(node) + .map(move |r| Expr::Call_from_sppf(self.parser, node, r)) + ), + P!(((((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => Iter::_13( + traverse!(all(sppf) ((((((_, _), _), _), _), [?]), _)) + .apply(node) + .map(move |r| Expr::MethodCall_from_sppf(self.parser, node, r)) + ), + P!(&[::gll::proc_macro::FlatTokenPat::Ident(Some("continue")),]) => Iter::_14( + traverse!(all(sppf) _) + .apply(node) + .map(move |r| Expr::Continue_from_sppf(self.parser, node, r)) + ), + P!((&[::gll::proc_macro::FlatTokenPat::Ident(Some("break")),] (Expr?))) => Iter::_15( + traverse!(all(sppf) (_, [?])) + .apply(node) + .map(move |r| Expr::Break_from_sppf(self.parser, node, r)) + ), + P!((&[::gll::proc_macro::FlatTokenPat::Ident(Some("return")),] (Expr?))) => Iter::_16( + traverse!(all(sppf) (_, [?])) + .apply(node) + .map(move |r| Expr::Return_from_sppf(self.parser, node, r)) + ), + _ => unreachable!(), + } + })}} + impl<'a, 'i, I: ::gll::runtime::Input> Expr<'a, 'i, I> { + pub fn parse_with( + input: I, + f: impl for<'b, 'i2> FnOnce( + &'b ::gll::runtime::Parser<'i2, _P, _C, I>, + ParseResult<'b, 'i2, I, Expr<'b, 'i2, I>>, + ) -> R, + ) -> R { + ::gll::runtime::Parser::with(input, |mut parser, range| { + let call = Call { + callee: _C::Expr, + range, + }; + parser.threads.spawn( + Continuation { + code: call.callee, + fn_input: call.range, + state: 0, + }, + call.range, + ); + parse(&mut parser); + let result = parser.memoizer.longest_result(call); + f(&parser, result.ok_or(ParseError::NoParse).and_then(|range| { + let handle = Handle { + node: ParseNode { kind: P!(Expr), range }, + parser: &parser, + _marker: PhantomData, + }; + if range == call.range { + Ok(handle) + } else { + Err(ParseError::TooShort(handle)) + } + })) + }) + } + }#[allow(non_camel_case_types)]pub struct ModuleContents<'a, 'i: 'a, I: 'a + ::gll::runtime::Input> {pub items: Handle<'a, 'i, I, [Expr<'a, 'i, I>]>,}impl<'a, 'i, I: ::gll::runtime::Input> fmt::Debug for ModuleContents<'a, 'i, I> {fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {let mut d = f.debug_struct("ModuleContents");d.field("items", &self.items);d.finish()}} + impl<'a, 'i, I: ::gll::runtime::Input> fmt::Debug for Handle<'a, 'i, I, ModuleContents<'a, 'i, I>> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?} => ", self.source_info())?; + let mut first = true; + for x in self.all() { + if !first { + write!(f, " | ")?; + } + first = false; + fmt::Debug::fmt(&x, f)?; + } + Ok(()) + } + } + impl<'a, 'i, I: ::gll::runtime::Input> ModuleContents<'a, 'i, I> { + fn from_sppf( + parser: &'a ::gll::runtime::Parser<'i, _P, _C, I>, + _node: ParseNode<'i, _P>, + _r: traverse!(typeof(ParseNode<'i, _P>) _), + ) -> Self {ModuleContents{items: Handle { node: _r, parser, _marker: PhantomData, },}}}impl<'a, 'i, I: ::gll::runtime::Input> Handle<'a, 'i, I, ModuleContents<'a, 'i, I>> {pub fn one(self) -> Result, Ambiguity> { + // HACK(eddyb) using a closure to catch `Err`s from `?` + (|| Ok({ + #[allow(unused_variables)] + let sppf = &self.parser.sppf; + let node = self.node.unpack_alias(); + let r = traverse!(one(sppf, node) _); + ModuleContents::from_sppf(self.parser, node, r) + }))().map_err(|::gll::runtime::MoreThanOne| Ambiguity(self)) + }pub fn all(self) -> impl Iterator> { + #[allow(unused_variables)] + let sppf = &self.parser.sppf; + let node = self.node.unpack_alias(); + traverse!(all(sppf) _) + .apply(node) + .map(move |r| ModuleContents::from_sppf(self.parser, node, r))}} + impl<'a, 'i, I: ::gll::runtime::Input> ModuleContents<'a, 'i, I> { + pub fn parse_with( + input: I, + f: impl for<'b, 'i2> FnOnce( + &'b ::gll::runtime::Parser<'i2, _P, _C, I>, + ParseResult<'b, 'i2, I, ModuleContents<'b, 'i2, I>>, + ) -> R, + ) -> R { + ::gll::runtime::Parser::with(input, |mut parser, range| { + let call = Call { + callee: _C::ModuleContents, + range, + }; + parser.threads.spawn( + Continuation { + code: call.callee, + fn_input: call.range, + state: 0, + }, + call.range, + ); + parse(&mut parser); + let result = parser.memoizer.longest_result(call); + f(&parser, result.ok_or(ParseError::NoParse).and_then(|range| { + let handle = Handle { + node: ParseNode { kind: P!(ModuleContents), range }, + parser: &parser, + _marker: PhantomData, + }; + if range == call.range { + Ok(handle) + } else { + Err(ParseError::TooShort(handle)) + } + })) + }) + } + } + fn parse(p: &mut ::gll::runtime::Parser<_P, _C, I>) + where I: ::gll::runtime::Input + { + while let Some(Call { callee: mut c, range: _range }) = p.threads.steal() { + match c.code {_C::IDENT => { + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Ident(None),]) { + p.ret(c, _range); + }}_C::PUNCT => { + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Punct { ch: None, joint: None },]) { + p.ret(c, _range); + }}_C::LITERAL => { + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Literal,]) { + p.ret(c, _range); + }}_C::TOKEN_TREE__0 => { + p.ret(c, _range);}_C::TOKEN_TREE__1 => { + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Delim(')'),]) { + c.code = _C::TOKEN_TREE__0; + p.threads.spawn(c, _range); + }}_C::TOKEN_TREE__2__0 => { + p.ret(c, _range);}_C::TOKEN_TREE__2__1 => { + c.code = _C::TOKEN_TREE__2__0; + p.call(Call { callee: _C::TOKEN_TREE__2, range: _range }, c);}_C::TOKEN_TREE__2 => { + c.code = _C::TOKEN_TREE__2__1; + p.call(Call { callee: _C::TOKEN_TREE, range: _range }, c); + c.code = _C::TOKEN_TREE__2__0; + p.threads.spawn(c, _range);}_C::TOKEN_TREE__3 => { + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Delim(']'),]) { + c.code = _C::TOKEN_TREE__0; + p.threads.spawn(c, _range); + }}_C::TOKEN_TREE__4__0 => { + p.ret(c, _range);}_C::TOKEN_TREE__4__1 => { + c.code = _C::TOKEN_TREE__4__0; + p.call(Call { callee: _C::TOKEN_TREE__4, range: _range }, c);}_C::TOKEN_TREE__4 => { + c.code = _C::TOKEN_TREE__4__1; + p.call(Call { callee: _C::TOKEN_TREE, range: _range }, c); + c.code = _C::TOKEN_TREE__4__0; + p.threads.spawn(c, _range);}_C::TOKEN_TREE__5 => { + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Delim('}'),]) { + c.code = _C::TOKEN_TREE__0; + p.threads.spawn(c, _range); + }}_C::TOKEN_TREE__6__0 => { + p.ret(c, _range);}_C::TOKEN_TREE__6__1 => { + c.code = _C::TOKEN_TREE__6__0; + p.call(Call { callee: _C::TOKEN_TREE__6, range: _range }, c);}_C::TOKEN_TREE__6 => { + c.code = _C::TOKEN_TREE__6__1; + p.call(Call { callee: _C::TOKEN_TREE, range: _range }, c); + c.code = _C::TOKEN_TREE__6__0; + p.threads.spawn(c, _range);}_C::TOKEN_TREE => { + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Ident(None),]) { + c.code = _C::TOKEN_TREE__0; + p.threads.spawn(c, _range); + } + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Punct { ch: None, joint: None },]) { + c.code = _C::TOKEN_TREE__0; + p.threads.spawn(c, _range); + } + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Literal,]) { + c.code = _C::TOKEN_TREE__0; + p.threads.spawn(c, _range); + } + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Delim('('),]) { + c.code = _C::TOKEN_TREE__1; + p.call(Call { callee: _C::TOKEN_TREE__2, range: _range }, c); + } + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Delim('['),]) { + c.code = _C::TOKEN_TREE__3; + p.call(Call { callee: _C::TOKEN_TREE__4, range: _range }, c); + } + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Delim('{'),]) { + c.code = _C::TOKEN_TREE__5; + p.call(Call { callee: _C::TOKEN_TREE__6, range: _range }, c); + }}_C::LIFETIME => { + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('\''), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Ident(None),]) { + p.ret(c, _range); + }}_C::Expr__0 => { + p.sppf.add(P!((LITERAL | ((&[::gll::proc_macro::FlatTokenPat::Delim('('),] Expr) &[::gll::proc_macro::FlatTokenPat::Delim(')'),]) | ((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('&'), joint: None },] (&[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),]?)) Expr) | (&[::gll::proc_macro::FlatTokenPat::Ident(Some("box")),] Expr) | (Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('?'), joint: None },]) | (((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) (Expr?)) | (((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('='), joint: None },]) Expr) | ((Expr &[::gll::proc_macro::FlatTokenPat::Ident(Some("as")),]) IDENT) | (((Expr &[::gll::proc_macro::FlatTokenPat::Delim('['),]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(']'),]) | (((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(']'),]) | ((((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(']'),]) | (((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),]) | ((((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),]) | ((((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),]) | &[::gll::proc_macro::FlatTokenPat::Ident(Some("continue")),] | (&[::gll::proc_macro::FlatTokenPat::Ident(Some("break")),] (Expr?)) | (&[::gll::proc_macro::FlatTokenPat::Ident(Some("return")),] (Expr?)))), c.fn_input.subtract_suffix(_range), c.state); + p.ret(c, _range);}_C::Expr__1__0 => { + p.sppf.add(P!((&[::gll::proc_macro::FlatTokenPat::Delim('('),] Expr)), c.fn_input.subtract_suffix(_range), c.state); + c.state = c.fn_input.subtract_suffix(_range).len(); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Delim(')'),]) { + p.sppf.add(P!(((&[::gll::proc_macro::FlatTokenPat::Delim('('),] Expr) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])), c.fn_input.subtract_suffix(_range), c.state); + p.ret(c, _range); + }}_C::Expr__1 => { + assert_eq!(_range.start(), c.fn_input.start()); + assert_eq!(_range.start(), c.fn_input.start()); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Delim('('),]) { + c.state = c.fn_input.subtract_suffix(_range).len(); + c.code = _C::Expr__1__0; + p.call(Call { callee: _C::Expr, range: _range }, c); + }}_C::Expr__2__0 => { + p.sppf.add(P!(((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('&'), joint: None },] (&[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),]?)) Expr)), c.fn_input.subtract_suffix(_range), c.state); + p.ret(c, _range);}_C::Expr__2__1 => { + p.sppf.add(P!((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('&'), joint: None },] (&[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),]?))), c.fn_input.subtract_suffix(_range), c.state); + c.state = c.fn_input.subtract_suffix(_range).len(); + c.code = _C::Expr__2__0; + p.call(Call { callee: _C::Expr, range: _range }, c);}_C::Expr__2 => { + assert_eq!(_range.start(), c.fn_input.start()); + assert_eq!(_range.start(), c.fn_input.start()); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('&'), joint: None },]) { + c.state = c.fn_input.subtract_suffix(_range).len(); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),]) { + c.code = _C::Expr__2__1; + p.threads.spawn(c, _range); + } + c.code = _C::Expr__2__1; + p.threads.spawn(c, _range); + }}_C::Expr__3__0 => { + p.sppf.add(P!((&[::gll::proc_macro::FlatTokenPat::Ident(Some("box")),] Expr)), c.fn_input.subtract_suffix(_range), c.state); + p.ret(c, _range);}_C::Expr__3 => { + assert_eq!(_range.start(), c.fn_input.start()); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Ident(Some("box")),]) { + c.state = c.fn_input.subtract_suffix(_range).len(); + c.code = _C::Expr__3__0; + p.call(Call { callee: _C::Expr, range: _range }, c); + }}_C::Expr__4__0 => { + c.state = c.fn_input.subtract_suffix(_range).len(); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('?'), joint: None },]) { + p.sppf.add(P!((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('?'), joint: None },])), c.fn_input.subtract_suffix(_range), c.state); + p.ret(c, _range); + }}_C::Expr__4 => { + assert_eq!(_range.start(), c.fn_input.start()); + c.code = _C::Expr__4__0; + p.call(Call { callee: _C::Expr, range: _range }, c);}_C::Expr__5__0 => { + p.sppf.add(P!((((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) (Expr?))), c.fn_input.subtract_suffix(_range), c.state); + p.ret(c, _range);}_C::Expr__5__1 => { + c.state = c.fn_input.subtract_suffix(_range).len(); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) { + p.sppf.add(P!(((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },])), c.fn_input.subtract_suffix(_range), c.state); + c.state = c.fn_input.subtract_suffix(_range).len(); + c.code = _C::Expr__5__0; + p.call(Call { callee: _C::Expr, range: _range }, c); + c.code = _C::Expr__5__0; + p.threads.spawn(c, _range); + }}_C::Expr__5 => { + assert_eq!(_range.start(), c.fn_input.start()); + assert_eq!(_range.start(), c.fn_input.start()); + c.code = _C::Expr__5__1; + p.call(Call { callee: _C::Expr, range: _range }, c); + c.code = _C::Expr__5__1; + p.threads.spawn(c, _range);}_C::Expr__6__0 => { + p.sppf.add(P!((((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('='), joint: None },]) Expr)), c.fn_input.subtract_suffix(_range), c.state); + p.ret(c, _range);}_C::Expr__6__1 => { + c.state = c.fn_input.subtract_suffix(_range).len(); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('='), joint: None },]) { + p.sppf.add(P!(((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('='), joint: None },])), c.fn_input.subtract_suffix(_range), c.state); + c.state = c.fn_input.subtract_suffix(_range).len(); + c.code = _C::Expr__6__0; + p.call(Call { callee: _C::Expr, range: _range }, c); + }}_C::Expr__6 => { + assert_eq!(_range.start(), c.fn_input.start()); + assert_eq!(_range.start(), c.fn_input.start()); + c.code = _C::Expr__6__1; + p.call(Call { callee: _C::Expr, range: _range }, c); + c.code = _C::Expr__6__1; + p.threads.spawn(c, _range);}_C::Expr__7__0 => { + p.sppf.add(P!(((Expr &[::gll::proc_macro::FlatTokenPat::Ident(Some("as")),]) IDENT)), c.fn_input.subtract_suffix(_range), c.state); + p.ret(c, _range);}_C::Expr__7__1 => { + c.state = c.fn_input.subtract_suffix(_range).len(); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Ident(Some("as")),]) { + p.sppf.add(P!((Expr &[::gll::proc_macro::FlatTokenPat::Ident(Some("as")),])), c.fn_input.subtract_suffix(_range), c.state); + c.state = c.fn_input.subtract_suffix(_range).len(); + c.code = _C::Expr__7__0; + p.call(Call { callee: _C::IDENT, range: _range }, c); + }}_C::Expr__7 => { + assert_eq!(_range.start(), c.fn_input.start()); + assert_eq!(_range.start(), c.fn_input.start()); + c.code = _C::Expr__7__1; + p.call(Call { callee: _C::Expr, range: _range }, c);}_C::Expr__8__0 => { + p.sppf.add(P!(((Expr &[::gll::proc_macro::FlatTokenPat::Delim('['),]) Expr)), c.fn_input.subtract_suffix(_range), c.state); + c.state = c.fn_input.subtract_suffix(_range).len(); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Delim(']'),]) { + p.sppf.add(P!((((Expr &[::gll::proc_macro::FlatTokenPat::Delim('['),]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])), c.fn_input.subtract_suffix(_range), c.state); + p.ret(c, _range); + }}_C::Expr__8__1 => { + c.state = c.fn_input.subtract_suffix(_range).len(); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Delim('['),]) { + p.sppf.add(P!((Expr &[::gll::proc_macro::FlatTokenPat::Delim('['),])), c.fn_input.subtract_suffix(_range), c.state); + c.state = c.fn_input.subtract_suffix(_range).len(); + c.code = _C::Expr__8__0; + p.call(Call { callee: _C::Expr, range: _range }, c); + }}_C::Expr__8 => { + assert_eq!(_range.start(), c.fn_input.start()); + assert_eq!(_range.start(), c.fn_input.start()); + assert_eq!(_range.start(), c.fn_input.start()); + c.code = _C::Expr__8__1; + p.call(Call { callee: _C::Expr, range: _range }, c);}_C::Expr__9__0 => { + p.sppf.add(P!(((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?))), c.fn_input.subtract_suffix(_range), c.state); + c.state = c.fn_input.subtract_suffix(_range).len(); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Delim(']'),]) { + p.sppf.add(P!((((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])), c.fn_input.subtract_suffix(_range), c.state); + p.ret(c, _range); + }}_C::Expr__9__1 => { + p.sppf.add(P!((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))), c.fn_input.subtract_suffix(_range), c.state); + c.state = c.fn_input.subtract_suffix(_range).len(); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]) { + c.code = _C::Expr__9__0; + p.threads.spawn(c, _range); + } + c.code = _C::Expr__9__0; + p.threads.spawn(c, _range);}_C::Expr__9__2__0 => { + p.sppf.add(P!((Expr+ % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])), c.fn_input.subtract_suffix(_range), c.state); + p.ret(c, _range);}_C::Expr__9__2__1__0 => { + p.sppf.add(P!((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },] (Expr+ % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))), c.fn_input.subtract_suffix(_range), c.state); + p.ret(c, _range);}_C::Expr__9__2__1 => { + assert_eq!(_range.start(), c.fn_input.start()); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]) { + c.state = c.fn_input.subtract_suffix(_range).len(); + c.code = _C::Expr__9__2__1__0; + p.call(Call { callee: _C::Expr__9__2, range: _range }, c); + }}_C::Expr__9__2__2 => { + c.state = c.fn_input.subtract_suffix(_range).len(); + c.code = _C::Expr__9__2__0; + p.call(Call { callee: _C::Expr__9__2__1, range: _range }, c); + c.code = _C::Expr__9__2__0; + p.threads.spawn(c, _range);}_C::Expr__9__2 => { + assert_eq!(_range.start(), c.fn_input.start()); + c.code = _C::Expr__9__2__2; + p.call(Call { callee: _C::Expr, range: _range }, c);}_C::Expr__9 => { + assert_eq!(_range.start(), c.fn_input.start()); + assert_eq!(_range.start(), c.fn_input.start()); + assert_eq!(_range.start(), c.fn_input.start()); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Delim('['),]) { + c.state = c.fn_input.subtract_suffix(_range).len(); + c.code = _C::Expr__9__1; + p.call(Call { callee: _C::Expr__9__2, range: _range }, c); + c.code = _C::Expr__9__1; + p.threads.spawn(c, _range); + }}_C::Expr__10__0 => { + p.sppf.add(P!((((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },]) Expr)), c.fn_input.subtract_suffix(_range), c.state); + c.state = c.fn_input.subtract_suffix(_range).len(); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Delim(']'),]) { + p.sppf.add(P!(((((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])), c.fn_input.subtract_suffix(_range), c.state); + p.ret(c, _range); + }}_C::Expr__10__1 => { + p.sppf.add(P!((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr)), c.fn_input.subtract_suffix(_range), c.state); + c.state = c.fn_input.subtract_suffix(_range).len(); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },]) { + p.sppf.add(P!(((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },])), c.fn_input.subtract_suffix(_range), c.state); + c.state = c.fn_input.subtract_suffix(_range).len(); + c.code = _C::Expr__10__0; + p.call(Call { callee: _C::Expr, range: _range }, c); + }}_C::Expr__10 => { + assert_eq!(_range.start(), c.fn_input.start()); + assert_eq!(_range.start(), c.fn_input.start()); + assert_eq!(_range.start(), c.fn_input.start()); + assert_eq!(_range.start(), c.fn_input.start()); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Delim('['),]) { + c.state = c.fn_input.subtract_suffix(_range).len(); + c.code = _C::Expr__10__1; + p.call(Call { callee: _C::Expr, range: _range }, c); + }}_C::Expr__11__0 => { + p.sppf.add(P!(((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?))), c.fn_input.subtract_suffix(_range), c.state); + c.state = c.fn_input.subtract_suffix(_range).len(); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Delim(')'),]) { + p.sppf.add(P!((((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])), c.fn_input.subtract_suffix(_range), c.state); + p.ret(c, _range); + }}_C::Expr__11__1 => { + p.sppf.add(P!((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))), c.fn_input.subtract_suffix(_range), c.state); + c.state = c.fn_input.subtract_suffix(_range).len(); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]) { + c.code = _C::Expr__11__0; + p.threads.spawn(c, _range); + } + c.code = _C::Expr__11__0; + p.threads.spawn(c, _range);}_C::Expr__11__2__0 => { + p.sppf.add(P!((Expr+ % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])), c.fn_input.subtract_suffix(_range), c.state); + p.ret(c, _range);}_C::Expr__11__2__1__0 => { + p.sppf.add(P!((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },] (Expr+ % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))), c.fn_input.subtract_suffix(_range), c.state); + p.ret(c, _range);}_C::Expr__11__2__1 => { + assert_eq!(_range.start(), c.fn_input.start()); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]) { + c.state = c.fn_input.subtract_suffix(_range).len(); + c.code = _C::Expr__11__2__1__0; + p.call(Call { callee: _C::Expr__11__2, range: _range }, c); + }}_C::Expr__11__2__2 => { + c.state = c.fn_input.subtract_suffix(_range).len(); + c.code = _C::Expr__11__2__0; + p.call(Call { callee: _C::Expr__11__2__1, range: _range }, c); + c.code = _C::Expr__11__2__0; + p.threads.spawn(c, _range);}_C::Expr__11__2 => { + assert_eq!(_range.start(), c.fn_input.start()); + c.code = _C::Expr__11__2__2; + p.call(Call { callee: _C::Expr, range: _range }, c);}_C::Expr__11 => { + assert_eq!(_range.start(), c.fn_input.start()); + assert_eq!(_range.start(), c.fn_input.start()); + assert_eq!(_range.start(), c.fn_input.start()); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Delim('('),]) { + c.state = c.fn_input.subtract_suffix(_range).len(); + c.code = _C::Expr__11__1; + p.call(Call { callee: _C::Expr__11__2, range: _range }, c); + c.code = _C::Expr__11__1; + p.threads.spawn(c, _range); + }}_C::Expr__12__0 => { + p.sppf.add(P!((((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?))), c.fn_input.subtract_suffix(_range), c.state); + c.state = c.fn_input.subtract_suffix(_range).len(); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Delim(')'),]) { + p.sppf.add(P!(((((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])), c.fn_input.subtract_suffix(_range), c.state); + p.ret(c, _range); + }}_C::Expr__12__1 => { + p.sppf.add(P!(((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))), c.fn_input.subtract_suffix(_range), c.state); + c.state = c.fn_input.subtract_suffix(_range).len(); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]) { + c.code = _C::Expr__12__0; + p.threads.spawn(c, _range); + } + c.code = _C::Expr__12__0; + p.threads.spawn(c, _range);}_C::Expr__12__2__0 => { + p.sppf.add(P!((Expr+ % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])), c.fn_input.subtract_suffix(_range), c.state); + p.ret(c, _range);}_C::Expr__12__2__1__0 => { + p.sppf.add(P!((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },] (Expr+ % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))), c.fn_input.subtract_suffix(_range), c.state); + p.ret(c, _range);}_C::Expr__12__2__1 => { + assert_eq!(_range.start(), c.fn_input.start()); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]) { + c.state = c.fn_input.subtract_suffix(_range).len(); + c.code = _C::Expr__12__2__1__0; + p.call(Call { callee: _C::Expr__12__2, range: _range }, c); + }}_C::Expr__12__2__2 => { + c.state = c.fn_input.subtract_suffix(_range).len(); + c.code = _C::Expr__12__2__0; + p.call(Call { callee: _C::Expr__12__2__1, range: _range }, c); + c.code = _C::Expr__12__2__0; + p.threads.spawn(c, _range);}_C::Expr__12__2 => { + assert_eq!(_range.start(), c.fn_input.start()); + c.code = _C::Expr__12__2__2; + p.call(Call { callee: _C::Expr, range: _range }, c);}_C::Expr__12__3 => { + c.state = c.fn_input.subtract_suffix(_range).len(); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Delim('('),]) { + p.sppf.add(P!((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),])), c.fn_input.subtract_suffix(_range), c.state); + c.state = c.fn_input.subtract_suffix(_range).len(); + c.code = _C::Expr__12__1; + p.call(Call { callee: _C::Expr__12__2, range: _range }, c); + c.code = _C::Expr__12__1; + p.threads.spawn(c, _range); + }}_C::Expr__12 => { + assert_eq!(_range.start(), c.fn_input.start()); + assert_eq!(_range.start(), c.fn_input.start()); + assert_eq!(_range.start(), c.fn_input.start()); + assert_eq!(_range.start(), c.fn_input.start()); + c.code = _C::Expr__12__3; + p.call(Call { callee: _C::Expr, range: _range }, c);}_C::Expr__13__0 => { + p.sppf.add(P!((((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?))), c.fn_input.subtract_suffix(_range), c.state); + c.state = c.fn_input.subtract_suffix(_range).len(); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Delim(')'),]) { + p.sppf.add(P!(((((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])), c.fn_input.subtract_suffix(_range), c.state); + p.ret(c, _range); + }}_C::Expr__13__1 => { + p.sppf.add(P!(((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))), c.fn_input.subtract_suffix(_range), c.state); + c.state = c.fn_input.subtract_suffix(_range).len(); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]) { + c.code = _C::Expr__13__0; + p.threads.spawn(c, _range); + } + c.code = _C::Expr__13__0; + p.threads.spawn(c, _range);}_C::Expr__13__2__0 => { + p.sppf.add(P!((Expr+ % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])), c.fn_input.subtract_suffix(_range), c.state); + p.ret(c, _range);}_C::Expr__13__2__1__0 => { + p.sppf.add(P!((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },] (Expr+ % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))), c.fn_input.subtract_suffix(_range), c.state); + p.ret(c, _range);}_C::Expr__13__2__1 => { + assert_eq!(_range.start(), c.fn_input.start()); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]) { + c.state = c.fn_input.subtract_suffix(_range).len(); + c.code = _C::Expr__13__2__1__0; + p.call(Call { callee: _C::Expr__13__2, range: _range }, c); + }}_C::Expr__13__2__2 => { + c.state = c.fn_input.subtract_suffix(_range).len(); + c.code = _C::Expr__13__2__0; + p.call(Call { callee: _C::Expr__13__2__1, range: _range }, c); + c.code = _C::Expr__13__2__0; + p.threads.spawn(c, _range);}_C::Expr__13__2 => { + assert_eq!(_range.start(), c.fn_input.start()); + c.code = _C::Expr__13__2__2; + p.call(Call { callee: _C::Expr, range: _range }, c);}_C::Expr__13__3 => { + p.sppf.add(P!(((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT)), c.fn_input.subtract_suffix(_range), c.state); + c.state = c.fn_input.subtract_suffix(_range).len(); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Delim('('),]) { + p.sppf.add(P!((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),])), c.fn_input.subtract_suffix(_range), c.state); + c.state = c.fn_input.subtract_suffix(_range).len(); + c.code = _C::Expr__13__1; + p.call(Call { callee: _C::Expr__13__2, range: _range }, c); + c.code = _C::Expr__13__1; + p.threads.spawn(c, _range); + }}_C::Expr__13__4 => { + c.state = c.fn_input.subtract_suffix(_range).len(); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) { + p.sppf.add(P!((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },])), c.fn_input.subtract_suffix(_range), c.state); + c.state = c.fn_input.subtract_suffix(_range).len(); + c.code = _C::Expr__13__3; + p.call(Call { callee: _C::IDENT, range: _range }, c); + }}_C::Expr__13 => { + assert_eq!(_range.start(), c.fn_input.start()); + assert_eq!(_range.start(), c.fn_input.start()); + assert_eq!(_range.start(), c.fn_input.start()); + assert_eq!(_range.start(), c.fn_input.start()); + assert_eq!(_range.start(), c.fn_input.start()); + assert_eq!(_range.start(), c.fn_input.start()); + c.code = _C::Expr__13__4; + p.call(Call { callee: _C::Expr, range: _range }, c);}_C::Expr__14__0 => { + p.sppf.add(P!((&[::gll::proc_macro::FlatTokenPat::Ident(Some("break")),] (Expr?))), c.fn_input.subtract_suffix(_range), c.state); + p.ret(c, _range);}_C::Expr__14 => { + assert_eq!(_range.start(), c.fn_input.start()); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Ident(Some("break")),]) { + c.state = c.fn_input.subtract_suffix(_range).len(); + c.code = _C::Expr__14__0; + p.call(Call { callee: _C::Expr, range: _range }, c); + c.code = _C::Expr__14__0; + p.threads.spawn(c, _range); + }}_C::Expr__15__0 => { + p.sppf.add(P!((&[::gll::proc_macro::FlatTokenPat::Ident(Some("return")),] (Expr?))), c.fn_input.subtract_suffix(_range), c.state); + p.ret(c, _range);}_C::Expr__15 => { + assert_eq!(_range.start(), c.fn_input.start()); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Ident(Some("return")),]) { + c.state = c.fn_input.subtract_suffix(_range).len(); + c.code = _C::Expr__15__0; + p.call(Call { callee: _C::Expr, range: _range }, c); + c.code = _C::Expr__15__0; + p.threads.spawn(c, _range); + }}_C::Expr => { + assert_eq!(_range.start(), c.fn_input.start()); + c.state = P!(LITERAL).to_usize(); + c.code = _C::Expr__0; + p.call(Call { callee: _C::LITERAL, range: _range }, c); + c.state = P!(((&[::gll::proc_macro::FlatTokenPat::Delim('('),] Expr) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])).to_usize(); + c.code = _C::Expr__0; + p.call(Call { callee: _C::Expr__1, range: _range }, c); + c.state = P!(((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('&'), joint: None },] (&[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),]?)) Expr)).to_usize(); + c.code = _C::Expr__0; + p.call(Call { callee: _C::Expr__2, range: _range }, c); + c.state = P!((&[::gll::proc_macro::FlatTokenPat::Ident(Some("box")),] Expr)).to_usize(); + c.code = _C::Expr__0; + p.call(Call { callee: _C::Expr__3, range: _range }, c); + c.state = P!((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('?'), joint: None },])).to_usize(); + c.code = _C::Expr__0; + p.call(Call { callee: _C::Expr__4, range: _range }, c); + c.state = P!((((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) (Expr?))).to_usize(); + c.code = _C::Expr__0; + p.call(Call { callee: _C::Expr__5, range: _range }, c); + c.state = P!((((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('='), joint: None },]) Expr)).to_usize(); + c.code = _C::Expr__0; + p.call(Call { callee: _C::Expr__6, range: _range }, c); + c.state = P!(((Expr &[::gll::proc_macro::FlatTokenPat::Ident(Some("as")),]) IDENT)).to_usize(); + c.code = _C::Expr__0; + p.call(Call { callee: _C::Expr__7, range: _range }, c); + c.state = P!((((Expr &[::gll::proc_macro::FlatTokenPat::Delim('['),]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])).to_usize(); + c.code = _C::Expr__0; + p.call(Call { callee: _C::Expr__8, range: _range }, c); + c.state = P!((((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])).to_usize(); + c.code = _C::Expr__0; + p.call(Call { callee: _C::Expr__9, range: _range }, c); + c.state = P!(((((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])).to_usize(); + c.code = _C::Expr__0; + p.call(Call { callee: _C::Expr__10, range: _range }, c); + c.state = P!((((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])).to_usize(); + c.code = _C::Expr__0; + p.call(Call { callee: _C::Expr__11, range: _range }, c); + c.state = P!(((((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])).to_usize(); + c.code = _C::Expr__0; + p.call(Call { callee: _C::Expr__12, range: _range }, c); + c.state = P!(((((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])).to_usize(); + c.code = _C::Expr__0; + p.call(Call { callee: _C::Expr__13, range: _range }, c); + c.state = P!(&[::gll::proc_macro::FlatTokenPat::Ident(Some("continue")),]).to_usize(); + if let Some(_range) = p.input_consume_left(_range, &[::gll::proc_macro::FlatTokenPat::Ident(Some("continue")),]) { + c.code = _C::Expr__0; + p.threads.spawn(c, _range); + } + c.state = P!((&[::gll::proc_macro::FlatTokenPat::Ident(Some("break")),] (Expr?))).to_usize(); + c.code = _C::Expr__0; + p.call(Call { callee: _C::Expr__14, range: _range }, c); + c.state = P!((&[::gll::proc_macro::FlatTokenPat::Ident(Some("return")),] (Expr?))).to_usize(); + c.code = _C::Expr__0; + p.call(Call { callee: _C::Expr__15, range: _range }, c);}_C::ModuleContents__0 => { + p.ret(c, _range);}_C::ModuleContents__1__0 => { + p.ret(c, _range);}_C::ModuleContents__1__1 => { + p.sppf.add(P!((Expr+ HACK)), c.fn_input.subtract_suffix(_range), c.state); + c.code = _C::ModuleContents__1__0; + p.threads.spawn(c, _range);}_C::ModuleContents__1__2 => { + c.state = c.fn_input.subtract_suffix(_range).len(); + c.code = _C::ModuleContents__1__1; + p.call(Call { callee: _C::ModuleContents__1, range: _range }, c);}_C::ModuleContents__1 => { + assert_eq!(_range.start(), c.fn_input.start()); + c.code = _C::ModuleContents__1__2; + p.call(Call { callee: _C::Expr, range: _range }, c); + c.code = _C::ModuleContents__1__0; + p.threads.spawn(c, _range);}_C::ModuleContents => { + c.code = _C::ModuleContents__0; + p.call(Call { callee: _C::ModuleContents__1, range: _range }, c);}} } }#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]pub enum _P { _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83,}impl fmt::Display for _P { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let s = match *self {P!(&[::gll::proc_macro::FlatTokenPat::Delim('('),]) => "&[::gll::proc_macro::FlatTokenPat::Delim(\'(\'),]",P!(&[::gll::proc_macro::FlatTokenPat::Delim(')'),]) => "&[::gll::proc_macro::FlatTokenPat::Delim(\')\'),]",P!(&[::gll::proc_macro::FlatTokenPat::Delim('['),]) => "&[::gll::proc_macro::FlatTokenPat::Delim(\'[\'),]",P!(&[::gll::proc_macro::FlatTokenPat::Delim(']'),]) => "&[::gll::proc_macro::FlatTokenPat::Delim(\']\'),]",P!(&[::gll::proc_macro::FlatTokenPat::Delim('{'),]) => "&[::gll::proc_macro::FlatTokenPat::Delim(\'{\'),]",P!(&[::gll::proc_macro::FlatTokenPat::Delim('}'),]) => "&[::gll::proc_macro::FlatTokenPat::Delim(\'}\'),]",P!(&[::gll::proc_macro::FlatTokenPat::Ident(None),]) => "&[::gll::proc_macro::FlatTokenPat::Ident(None),]",P!(&[::gll::proc_macro::FlatTokenPat::Ident(Some("as")),]) => "&[::gll::proc_macro::FlatTokenPat::Ident(Some(\"as\")),]",P!(&[::gll::proc_macro::FlatTokenPat::Ident(Some("box")),]) => "&[::gll::proc_macro::FlatTokenPat::Ident(Some(\"box\")),]",P!(&[::gll::proc_macro::FlatTokenPat::Ident(Some("break")),]) => "&[::gll::proc_macro::FlatTokenPat::Ident(Some(\"break\")),]",P!(&[::gll::proc_macro::FlatTokenPat::Ident(Some("continue")),]) => "&[::gll::proc_macro::FlatTokenPat::Ident(Some(\"continue\")),]",P!(&[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),]) => "&[::gll::proc_macro::FlatTokenPat::Ident(Some(\"mut\")),]",P!(&[::gll::proc_macro::FlatTokenPat::Ident(Some("return")),]) => "&[::gll::proc_macro::FlatTokenPat::Ident(Some(\"return\")),]",P!(&[::gll::proc_macro::FlatTokenPat::Literal,]) => "&[::gll::proc_macro::FlatTokenPat::Literal,]",P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: None, joint: None },]) => "&[::gll::proc_macro::FlatTokenPat::Punct { ch: None, joint: None },]",P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('&'), joint: None },]) => "&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'&\'), joint: None },]",P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]) => "&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },]",P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) => "&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'.\'), joint: None },]",P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) => "&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'.\'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'.\'), joint: None },]",P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('='), joint: None },]) => "&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'.\'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'.\'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'=\'), joint: None },]",P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },]) => "&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\';\'), joint: None },]",P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('?'), joint: None },]) => "&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'?\'), joint: None },]",P!((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))) => "(&[::gll::proc_macro::FlatTokenPat::Delim(\'(\'),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },]))",P!((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (TOKEN_TREE*))) => "(&[::gll::proc_macro::FlatTokenPat::Delim(\'(\'),] (TOKEN_TREE*))",P!((&[::gll::proc_macro::FlatTokenPat::Delim('('),] Expr)) => "(&[::gll::proc_macro::FlatTokenPat::Delim(\'(\'),] Expr)",P!((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))) => "(&[::gll::proc_macro::FlatTokenPat::Delim(\'[\'),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },]))",P!((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (TOKEN_TREE*))) => "(&[::gll::proc_macro::FlatTokenPat::Delim(\'[\'),] (TOKEN_TREE*))",P!((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr)) => "(&[::gll::proc_macro::FlatTokenPat::Delim(\'[\'),] Expr)",P!((&[::gll::proc_macro::FlatTokenPat::Delim('{'),] (TOKEN_TREE*))) => "(&[::gll::proc_macro::FlatTokenPat::Delim(\'{\'),] (TOKEN_TREE*))",P!((&[::gll::proc_macro::FlatTokenPat::Ident(Some("box")),] Expr)) => "(&[::gll::proc_macro::FlatTokenPat::Ident(Some(\"box\")),] Expr)",P!((&[::gll::proc_macro::FlatTokenPat::Ident(Some("break")),] (Expr?))) => "(&[::gll::proc_macro::FlatTokenPat::Ident(Some(\"break\")),] (Expr?))",P!((&[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),]?)) => "(&[::gll::proc_macro::FlatTokenPat::Ident(Some(\"mut\")),]?)",P!((&[::gll::proc_macro::FlatTokenPat::Ident(Some("return")),] (Expr?))) => "(&[::gll::proc_macro::FlatTokenPat::Ident(Some(\"return\")),] (Expr?))",P!((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('&'), joint: None },] (&[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),]?))) => "(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'&\'), joint: None },] (&[::gll::proc_macro::FlatTokenPat::Ident(Some(\"mut\")),]?))",P!((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },] (Expr+ % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))) => "(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },] (Expr+ % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },]))",P!((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) => "(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },]?)",P!(((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?))) => "((&[::gll::proc_macro::FlatTokenPat::Delim(\'(\'),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },]?))",P!(((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (TOKEN_TREE*)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => "((&[::gll::proc_macro::FlatTokenPat::Delim(\'(\'),] (TOKEN_TREE*)) &[::gll::proc_macro::FlatTokenPat::Delim(\')\'),])",P!(((&[::gll::proc_macro::FlatTokenPat::Delim('('),] Expr) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => "((&[::gll::proc_macro::FlatTokenPat::Delim(\'(\'),] Expr) &[::gll::proc_macro::FlatTokenPat::Delim(\')\'),])",P!(((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?))) => "((&[::gll::proc_macro::FlatTokenPat::Delim(\'[\'),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },]?))",P!(((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (TOKEN_TREE*)) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])) => "((&[::gll::proc_macro::FlatTokenPat::Delim(\'[\'),] (TOKEN_TREE*)) &[::gll::proc_macro::FlatTokenPat::Delim(\']\'),])",P!(((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },])) => "((&[::gll::proc_macro::FlatTokenPat::Delim(\'[\'),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\';\'), joint: None },])",P!(((&[::gll::proc_macro::FlatTokenPat::Delim('{'),] (TOKEN_TREE*)) &[::gll::proc_macro::FlatTokenPat::Delim('}'),])) => "((&[::gll::proc_macro::FlatTokenPat::Delim(\'{\'),] (TOKEN_TREE*)) &[::gll::proc_macro::FlatTokenPat::Delim(\'}\'),])",P!(((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('&'), joint: None },] (&[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),]?)) Expr)) => "((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'&\'), joint: None },] (&[::gll::proc_macro::FlatTokenPat::Ident(Some(\"mut\")),]?)) Expr)",P!(((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },] (Expr+ % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))?)) => "((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },] (Expr+ % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },]))?)",P!((((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => "(((&[::gll::proc_macro::FlatTokenPat::Delim(\'(\'),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(\')\'),])",P!((((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])) => "(((&[::gll::proc_macro::FlatTokenPat::Delim(\'[\'),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(\']\'),])",P!((((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },]) Expr)) => "(((&[::gll::proc_macro::FlatTokenPat::Delim(\'[\'),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\';\'), joint: None },]) Expr)",P!(((((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])) => "((((&[::gll::proc_macro::FlatTokenPat::Delim(\'[\'),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\';\'), joint: None },]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(\']\'),])",P!(((((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => "((((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'.\'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim(\'(\'),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(\')\'),])",P!((((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?))) => "(((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'.\'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim(\'(\'),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },]?))",P!(((((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => "((((Expr &[::gll::proc_macro::FlatTokenPat::Delim(\'(\'),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(\')\'),])",P!(((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))) => "((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'.\'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim(\'(\'),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },]))",P!((((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?))) => "(((Expr &[::gll::proc_macro::FlatTokenPat::Delim(\'(\'),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },]?))",P!((((Expr &[::gll::proc_macro::FlatTokenPat::Delim('['),]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])) => "(((Expr &[::gll::proc_macro::FlatTokenPat::Delim(\'[\'),]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(\']\'),])",P!((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),])) => "(((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'.\'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim(\'(\'),])",P!((((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) (Expr?))) => "(((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'.\'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'.\'), joint: None },]) (Expr?))",P!((((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('='), joint: None },]) Expr)) => "(((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'.\'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'.\'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'=\'), joint: None },]) Expr)",P!(((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))) => "((Expr &[::gll::proc_macro::FlatTokenPat::Delim(\'(\'),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },]))",P!(((Expr &[::gll::proc_macro::FlatTokenPat::Delim('['),]) Expr)) => "((Expr &[::gll::proc_macro::FlatTokenPat::Delim(\'[\'),]) Expr)",P!(((Expr &[::gll::proc_macro::FlatTokenPat::Ident(Some("as")),]) IDENT)) => "((Expr &[::gll::proc_macro::FlatTokenPat::Ident(Some(\"as\")),]) IDENT)",P!(((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT)) => "((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'.\'), joint: None },]) IDENT)",P!(((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },])) => "((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'.\'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'.\'), joint: None },])",P!(((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('='), joint: None },])) => "((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'.\'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'.\'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'=\'), joint: None },])",P!((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),])) => "(Expr &[::gll::proc_macro::FlatTokenPat::Delim(\'(\'),])",P!((Expr &[::gll::proc_macro::FlatTokenPat::Delim('['),])) => "(Expr &[::gll::proc_macro::FlatTokenPat::Delim(\'[\'),])",P!((Expr &[::gll::proc_macro::FlatTokenPat::Ident(Some("as")),])) => "(Expr &[::gll::proc_macro::FlatTokenPat::Ident(Some(\"as\")),])",P!((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },])) => "(Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'.\'), joint: None },])",P!((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('?'), joint: None },])) => "(Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'?\'), joint: None },])",P!((Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) => "(Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },])",P!((Expr*)) => "(Expr*)",P!((Expr+ % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) => "(Expr+ % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },])",P!((Expr+ HACK)) => "(Expr+ HACK)",P!((Expr?)) => "(Expr?)",P!((LITERAL | ((&[::gll::proc_macro::FlatTokenPat::Delim('('),] Expr) &[::gll::proc_macro::FlatTokenPat::Delim(')'),]) | ((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('&'), joint: None },] (&[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),]?)) Expr) | (&[::gll::proc_macro::FlatTokenPat::Ident(Some("box")),] Expr) | (Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('?'), joint: None },]) | (((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) (Expr?)) | (((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('='), joint: None },]) Expr) | ((Expr &[::gll::proc_macro::FlatTokenPat::Ident(Some("as")),]) IDENT) | (((Expr &[::gll::proc_macro::FlatTokenPat::Delim('['),]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(']'),]) | (((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(']'),]) | ((((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(']'),]) | (((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),]) | ((((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),]) | ((((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),]) | &[::gll::proc_macro::FlatTokenPat::Ident(Some("continue")),] | (&[::gll::proc_macro::FlatTokenPat::Ident(Some("break")),] (Expr?)) | (&[::gll::proc_macro::FlatTokenPat::Ident(Some("return")),] (Expr?)))) => "(LITERAL | ((&[::gll::proc_macro::FlatTokenPat::Delim(\'(\'),] Expr) &[::gll::proc_macro::FlatTokenPat::Delim(\')\'),]) | ((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'&\'), joint: None },] (&[::gll::proc_macro::FlatTokenPat::Ident(Some(\"mut\")),]?)) Expr) | (&[::gll::proc_macro::FlatTokenPat::Ident(Some(\"box\")),] Expr) | (Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'?\'), joint: None },]) | (((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'.\'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'.\'), joint: None },]) (Expr?)) | (((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'.\'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'.\'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'=\'), joint: None },]) Expr) | ((Expr &[::gll::proc_macro::FlatTokenPat::Ident(Some(\"as\")),]) IDENT) | (((Expr &[::gll::proc_macro::FlatTokenPat::Delim(\'[\'),]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(\']\'),]) | (((&[::gll::proc_macro::FlatTokenPat::Delim(\'[\'),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(\']\'),]) | ((((&[::gll::proc_macro::FlatTokenPat::Delim(\'[\'),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\';\'), joint: None },]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(\']\'),]) | (((&[::gll::proc_macro::FlatTokenPat::Delim(\'(\'),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(\')\'),]) | ((((Expr &[::gll::proc_macro::FlatTokenPat::Delim(\'(\'),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(\')\'),]) | ((((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\'.\'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim(\'(\'),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(\',\'), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(\')\'),]) | &[::gll::proc_macro::FlatTokenPat::Ident(Some(\"continue\")),] | (&[::gll::proc_macro::FlatTokenPat::Ident(Some(\"break\")),] (Expr?)) | (&[::gll::proc_macro::FlatTokenPat::Ident(Some(\"return\")),] (Expr?)))",P!((TOKEN_TREE*)) => "(TOKEN_TREE*)",P!((TOKEN_TREE+ HACK)) => "(TOKEN_TREE+ HACK)",P!(Expr) => "Expr",P!(IDENT) => "IDENT",P!(LIFETIME) => "LIFETIME",P!(LITERAL) => "LITERAL",P!(ModuleContents) => "ModuleContents",P!(PUNCT) => "PUNCT",P!(TOKEN_TREE) => "TOKEN_TREE",};write!(f, "{}", s)} }impl ParseNodeKind for _P { + fn shape(self) -> ParseNodeShape { + match self {P!(&[::gll::proc_macro::FlatTokenPat::Delim('('),]) => ParseNodeShape::Opaque,P!(&[::gll::proc_macro::FlatTokenPat::Delim(')'),]) => ParseNodeShape::Opaque,P!(&[::gll::proc_macro::FlatTokenPat::Delim('['),]) => ParseNodeShape::Opaque,P!(&[::gll::proc_macro::FlatTokenPat::Delim(']'),]) => ParseNodeShape::Opaque,P!(&[::gll::proc_macro::FlatTokenPat::Delim('{'),]) => ParseNodeShape::Opaque,P!(&[::gll::proc_macro::FlatTokenPat::Delim('}'),]) => ParseNodeShape::Opaque,P!(&[::gll::proc_macro::FlatTokenPat::Ident(None),]) => ParseNodeShape::Opaque,P!(&[::gll::proc_macro::FlatTokenPat::Ident(Some("as")),]) => ParseNodeShape::Opaque,P!(&[::gll::proc_macro::FlatTokenPat::Ident(Some("box")),]) => ParseNodeShape::Opaque,P!(&[::gll::proc_macro::FlatTokenPat::Ident(Some("break")),]) => ParseNodeShape::Opaque,P!(&[::gll::proc_macro::FlatTokenPat::Ident(Some("continue")),]) => ParseNodeShape::Opaque,P!(&[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),]) => ParseNodeShape::Opaque,P!(&[::gll::proc_macro::FlatTokenPat::Ident(Some("return")),]) => ParseNodeShape::Opaque,P!(&[::gll::proc_macro::FlatTokenPat::Literal,]) => ParseNodeShape::Opaque,P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: None, joint: None },]) => ParseNodeShape::Opaque,P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('&'), joint: None },]) => ParseNodeShape::Opaque,P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]) => ParseNodeShape::Opaque,P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) => ParseNodeShape::Opaque,P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) => ParseNodeShape::Opaque,P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('='), joint: None },]) => ParseNodeShape::Opaque,P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },]) => ParseNodeShape::Opaque,P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('?'), joint: None },]) => ParseNodeShape::Opaque,P!((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))) => ParseNodeShape::Split(P!(&[::gll::proc_macro::FlatTokenPat::Delim('('),]), P!((Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))),P!((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (TOKEN_TREE*))) => ParseNodeShape::Split(P!(&[::gll::proc_macro::FlatTokenPat::Delim('('),]), P!((TOKEN_TREE*))),P!((&[::gll::proc_macro::FlatTokenPat::Delim('('),] Expr)) => ParseNodeShape::Split(P!(&[::gll::proc_macro::FlatTokenPat::Delim('('),]), P!(Expr)),P!((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))) => ParseNodeShape::Split(P!(&[::gll::proc_macro::FlatTokenPat::Delim('['),]), P!((Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))),P!((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (TOKEN_TREE*))) => ParseNodeShape::Split(P!(&[::gll::proc_macro::FlatTokenPat::Delim('['),]), P!((TOKEN_TREE*))),P!((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr)) => ParseNodeShape::Split(P!(&[::gll::proc_macro::FlatTokenPat::Delim('['),]), P!(Expr)),P!((&[::gll::proc_macro::FlatTokenPat::Delim('{'),] (TOKEN_TREE*))) => ParseNodeShape::Split(P!(&[::gll::proc_macro::FlatTokenPat::Delim('{'),]), P!((TOKEN_TREE*))),P!((&[::gll::proc_macro::FlatTokenPat::Ident(Some("box")),] Expr)) => ParseNodeShape::Split(P!(&[::gll::proc_macro::FlatTokenPat::Ident(Some("box")),]), P!(Expr)),P!((&[::gll::proc_macro::FlatTokenPat::Ident(Some("break")),] (Expr?))) => ParseNodeShape::Split(P!(&[::gll::proc_macro::FlatTokenPat::Ident(Some("break")),]), P!((Expr?))),P!((&[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),]?)) => ParseNodeShape::Opt(P!(&[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),])),P!((&[::gll::proc_macro::FlatTokenPat::Ident(Some("return")),] (Expr?))) => ParseNodeShape::Split(P!(&[::gll::proc_macro::FlatTokenPat::Ident(Some("return")),]), P!((Expr?))),P!((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('&'), joint: None },] (&[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),]?))) => ParseNodeShape::Split(P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('&'), joint: None },]), P!((&[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),]?))),P!((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },] (Expr+ % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))) => ParseNodeShape::Split(P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]), P!((Expr+ % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))),P!((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) => ParseNodeShape::Opt(P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])),P!(((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?))) => ParseNodeShape::Split(P!((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))), P!((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?))),P!(((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (TOKEN_TREE*)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => ParseNodeShape::Split(P!((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (TOKEN_TREE*))), P!(&[::gll::proc_macro::FlatTokenPat::Delim(')'),])),P!(((&[::gll::proc_macro::FlatTokenPat::Delim('('),] Expr) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => ParseNodeShape::Split(P!((&[::gll::proc_macro::FlatTokenPat::Delim('('),] Expr)), P!(&[::gll::proc_macro::FlatTokenPat::Delim(')'),])),P!(((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?))) => ParseNodeShape::Split(P!((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))), P!((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?))),P!(((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (TOKEN_TREE*)) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])) => ParseNodeShape::Split(P!((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (TOKEN_TREE*))), P!(&[::gll::proc_macro::FlatTokenPat::Delim(']'),])),P!(((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },])) => ParseNodeShape::Split(P!((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr)), P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },])),P!(((&[::gll::proc_macro::FlatTokenPat::Delim('{'),] (TOKEN_TREE*)) &[::gll::proc_macro::FlatTokenPat::Delim('}'),])) => ParseNodeShape::Split(P!((&[::gll::proc_macro::FlatTokenPat::Delim('{'),] (TOKEN_TREE*))), P!(&[::gll::proc_macro::FlatTokenPat::Delim('}'),])),P!(((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('&'), joint: None },] (&[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),]?)) Expr)) => ParseNodeShape::Split(P!((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('&'), joint: None },] (&[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),]?))), P!(Expr)),P!(((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },] (Expr+ % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))?)) => ParseNodeShape::Opt(P!((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },] (Expr+ % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])))),P!((((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => ParseNodeShape::Split(P!(((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?))), P!(&[::gll::proc_macro::FlatTokenPat::Delim(')'),])),P!((((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])) => ParseNodeShape::Split(P!(((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?))), P!(&[::gll::proc_macro::FlatTokenPat::Delim(']'),])),P!((((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },]) Expr)) => ParseNodeShape::Split(P!(((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },])), P!(Expr)),P!(((((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])) => ParseNodeShape::Split(P!((((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },]) Expr)), P!(&[::gll::proc_macro::FlatTokenPat::Delim(']'),])),P!(((((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => ParseNodeShape::Split(P!((((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?))), P!(&[::gll::proc_macro::FlatTokenPat::Delim(')'),])),P!((((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?))) => ParseNodeShape::Split(P!(((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))), P!((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?))),P!(((((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),])) => ParseNodeShape::Split(P!((((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?))), P!(&[::gll::proc_macro::FlatTokenPat::Delim(')'),])),P!(((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))) => ParseNodeShape::Split(P!((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),])), P!((Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))),P!((((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?))) => ParseNodeShape::Split(P!(((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))), P!((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?))),P!((((Expr &[::gll::proc_macro::FlatTokenPat::Delim('['),]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(']'),])) => ParseNodeShape::Split(P!(((Expr &[::gll::proc_macro::FlatTokenPat::Delim('['),]) Expr)), P!(&[::gll::proc_macro::FlatTokenPat::Delim(']'),])),P!((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),])) => ParseNodeShape::Split(P!(((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT)), P!(&[::gll::proc_macro::FlatTokenPat::Delim('('),])),P!((((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) (Expr?))) => ParseNodeShape::Split(P!(((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },])), P!((Expr?))),P!((((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('='), joint: None },]) Expr)) => ParseNodeShape::Split(P!(((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('='), joint: None },])), P!(Expr)),P!(((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))) => ParseNodeShape::Split(P!((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),])), P!((Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))),P!(((Expr &[::gll::proc_macro::FlatTokenPat::Delim('['),]) Expr)) => ParseNodeShape::Split(P!((Expr &[::gll::proc_macro::FlatTokenPat::Delim('['),])), P!(Expr)),P!(((Expr &[::gll::proc_macro::FlatTokenPat::Ident(Some("as")),]) IDENT)) => ParseNodeShape::Split(P!((Expr &[::gll::proc_macro::FlatTokenPat::Ident(Some("as")),])), P!(IDENT)),P!(((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT)) => ParseNodeShape::Split(P!((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },])), P!(IDENT)),P!(((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },])) => ParseNodeShape::Split(P!((Expr?)), P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },])),P!(((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('='), joint: None },])) => ParseNodeShape::Split(P!((Expr?)), P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('='), joint: None },])),P!((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),])) => ParseNodeShape::Split(P!(Expr), P!(&[::gll::proc_macro::FlatTokenPat::Delim('('),])),P!((Expr &[::gll::proc_macro::FlatTokenPat::Delim('['),])) => ParseNodeShape::Split(P!(Expr), P!(&[::gll::proc_macro::FlatTokenPat::Delim('['),])),P!((Expr &[::gll::proc_macro::FlatTokenPat::Ident(Some("as")),])) => ParseNodeShape::Split(P!(Expr), P!(&[::gll::proc_macro::FlatTokenPat::Ident(Some("as")),])),P!((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },])) => ParseNodeShape::Split(P!(Expr), P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },])),P!((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('?'), joint: None },])) => ParseNodeShape::Split(P!(Expr), P!(&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('?'), joint: None },])),P!((Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) => ParseNodeShape::Opt(P!((Expr+ % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))),P!((Expr*)) => ParseNodeShape::Opt(P!((Expr+ HACK))),P!((Expr+ % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) => ParseNodeShape::Split(P!(Expr), P!(((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },] (Expr+ % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]))?))),P!((Expr+ HACK)) => ParseNodeShape::Split(P!(Expr), P!((Expr*))),P!((Expr?)) => ParseNodeShape::Opt(P!(Expr)),P!((LITERAL | ((&[::gll::proc_macro::FlatTokenPat::Delim('('),] Expr) &[::gll::proc_macro::FlatTokenPat::Delim(')'),]) | ((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('&'), joint: None },] (&[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),]?)) Expr) | (&[::gll::proc_macro::FlatTokenPat::Ident(Some("box")),] Expr) | (Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('?'), joint: None },]) | (((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) (Expr?)) | (((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('='), joint: None },]) Expr) | ((Expr &[::gll::proc_macro::FlatTokenPat::Ident(Some("as")),]) IDENT) | (((Expr &[::gll::proc_macro::FlatTokenPat::Delim('['),]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(']'),]) | (((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(']'),]) | ((((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(']'),]) | (((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),]) | ((((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),]) | ((((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),]) | &[::gll::proc_macro::FlatTokenPat::Ident(Some("continue")),] | (&[::gll::proc_macro::FlatTokenPat::Ident(Some("break")),] (Expr?)) | (&[::gll::proc_macro::FlatTokenPat::Ident(Some("return")),] (Expr?)))) => ParseNodeShape::Choice,P!((TOKEN_TREE*)) => ParseNodeShape::Opt(P!((TOKEN_TREE+ HACK))),P!((TOKEN_TREE+ HACK)) => ParseNodeShape::Split(P!(TOKEN_TREE), P!((TOKEN_TREE*))),P!(Expr) => ParseNodeShape::Alias(P!((LITERAL | ((&[::gll::proc_macro::FlatTokenPat::Delim('('),] Expr) &[::gll::proc_macro::FlatTokenPat::Delim(')'),]) | ((&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('&'), joint: None },] (&[::gll::proc_macro::FlatTokenPat::Ident(Some("mut")),]?)) Expr) | (&[::gll::proc_macro::FlatTokenPat::Ident(Some("box")),] Expr) | (Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('?'), joint: None },]) | (((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) (Expr?)) | (((Expr?) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: Some(true) },::gll::proc_macro::FlatTokenPat::Punct { ch: Some('='), joint: None },]) Expr) | ((Expr &[::gll::proc_macro::FlatTokenPat::Ident(Some("as")),]) IDENT) | (((Expr &[::gll::proc_macro::FlatTokenPat::Delim('['),]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(']'),]) | (((&[::gll::proc_macro::FlatTokenPat::Delim('['),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(']'),]) | ((((&[::gll::proc_macro::FlatTokenPat::Delim('['),] Expr) &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(';'), joint: None },]) Expr) &[::gll::proc_macro::FlatTokenPat::Delim(']'),]) | (((&[::gll::proc_macro::FlatTokenPat::Delim('('),] (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),]) | ((((Expr &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),]) | ((((((Expr &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some('.'), joint: None },]) IDENT) &[::gll::proc_macro::FlatTokenPat::Delim('('),]) (Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) (&[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },]?)) &[::gll::proc_macro::FlatTokenPat::Delim(')'),]) | &[::gll::proc_macro::FlatTokenPat::Ident(Some("continue")),] | (&[::gll::proc_macro::FlatTokenPat::Ident(Some("break")),] (Expr?)) | (&[::gll::proc_macro::FlatTokenPat::Ident(Some("return")),] (Expr?))))),P!(IDENT) => ParseNodeShape::Opaque,P!(LIFETIME) => ParseNodeShape::Opaque,P!(LITERAL) => ParseNodeShape::Opaque,P!(ModuleContents) => ParseNodeShape::Alias(P!((Expr*))),P!(PUNCT) => ParseNodeShape::Opaque,P!(TOKEN_TREE) => ParseNodeShape::Opaque,} }fn from_usize(i: usize) -> Self { + match i { + 0 => _P::_0, + 1 => _P::_1, + 2 => _P::_2, + 3 => _P::_3, + 4 => _P::_4, + 5 => _P::_5, + 6 => _P::_6, + 7 => _P::_7, + 8 => _P::_8, + 9 => _P::_9, + 10 => _P::_10, + 11 => _P::_11, + 12 => _P::_12, + 13 => _P::_13, + 14 => _P::_14, + 15 => _P::_15, + 16 => _P::_16, + 17 => _P::_17, + 18 => _P::_18, + 19 => _P::_19, + 20 => _P::_20, + 21 => _P::_21, + 22 => _P::_22, + 23 => _P::_23, + 24 => _P::_24, + 25 => _P::_25, + 26 => _P::_26, + 27 => _P::_27, + 28 => _P::_28, + 29 => _P::_29, + 30 => _P::_30, + 31 => _P::_31, + 32 => _P::_32, + 33 => _P::_33, + 34 => _P::_34, + 35 => _P::_35, + 36 => _P::_36, + 37 => _P::_37, + 38 => _P::_38, + 39 => _P::_39, + 40 => _P::_40, + 41 => _P::_41, + 42 => _P::_42, + 43 => _P::_43, + 44 => _P::_44, + 45 => _P::_45, + 46 => _P::_46, + 47 => _P::_47, + 48 => _P::_48, + 49 => _P::_49, + 50 => _P::_50, + 51 => _P::_51, + 52 => _P::_52, + 53 => _P::_53, + 54 => _P::_54, + 55 => _P::_55, + 56 => _P::_56, + 57 => _P::_57, + 58 => _P::_58, + 59 => _P::_59, + 60 => _P::_60, + 61 => _P::_61, + 62 => _P::_62, + 63 => _P::_63, + 64 => _P::_64, + 65 => _P::_65, + 66 => _P::_66, + 67 => _P::_67, + 68 => _P::_68, + 69 => _P::_69, + 70 => _P::_70, + 71 => _P::_71, + 72 => _P::_72, + 73 => _P::_73, + 74 => _P::_74, + 75 => _P::_75, + 76 => _P::_76, + 77 => _P::_77, + 78 => _P::_78, + 79 => _P::_79, + 80 => _P::_80, + 81 => _P::_81, + 82 => _P::_82, + 83 => _P::_83,_ => unreachable!(),} }fn to_usize(self) -> usize { self as usize }}impl<'a, 'i, I: ::gll::runtime::Input> fmt::Debug for Handle<'a, 'i, I, Any> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self.node.kind { + P!((Expr* % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) => write!(f, "{:?}", Handle::<_, [Expr<_>]> { + node: self.node, + parser: self.parser, + _marker: PhantomData, + }), + P!((Expr*)) => write!(f, "{:?}", Handle::<_, [Expr<_>]> { + node: self.node, + parser: self.parser, + _marker: PhantomData, + }), + P!((Expr+ % &[::gll::proc_macro::FlatTokenPat::Punct { ch: Some(','), joint: None },])) => write!(f, "{:?}", Handle::<_, [Expr<_>]> { + node: self.node, + parser: self.parser, + _marker: PhantomData, + }), + P!((Expr+ HACK)) => write!(f, "{:?}", Handle::<_, [Expr<_>]> { + node: self.node, + parser: self.parser, + _marker: PhantomData, + }), + P!((TOKEN_TREE*)) => write!(f, "{:?}", Handle::<_, [TOKEN_TREE<_>]> { + node: self.node, + parser: self.parser, + _marker: PhantomData, + }), + P!((TOKEN_TREE+ HACK)) => write!(f, "{:?}", Handle::<_, [TOKEN_TREE<_>]> { + node: self.node, + parser: self.parser, + _marker: PhantomData, + }), + P!(Expr) => write!(f, "{:?}", Handle::<_, Expr<_>> { + node: self.node, + parser: self.parser, + _marker: PhantomData, + }), + P!(IDENT) => write!(f, "{:?}", Handle::<_, IDENT<_>> { + node: self.node, + parser: self.parser, + _marker: PhantomData, + }), + P!(LIFETIME) => write!(f, "{:?}", Handle::<_, LIFETIME<_>> { + node: self.node, + parser: self.parser, + _marker: PhantomData, + }), + P!(LITERAL) => write!(f, "{:?}", Handle::<_, LITERAL<_>> { + node: self.node, + parser: self.parser, + _marker: PhantomData, + }), + P!(ModuleContents) => write!(f, "{:?}", Handle::<_, ModuleContents<_>> { + node: self.node, + parser: self.parser, + _marker: PhantomData, + }), + P!(PUNCT) => write!(f, "{:?}", Handle::<_, PUNCT<_>> { + node: self.node, + parser: self.parser, + _marker: PhantomData, + }), + P!(TOKEN_TREE) => write!(f, "{:?}", Handle::<_, TOKEN_TREE<_>> { + node: self.node, + parser: self.parser, + _marker: PhantomData, + }), + _ => write!(f, "{:?}", Handle::<_, ()> { + node: self.node, + parser: self.parser, + _marker: PhantomData, + }),} } } + #[allow(non_camel_case_types)] + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] + pub enum _C {IDENT,PUNCT,LITERAL,TOKEN_TREE,LIFETIME,Expr,ModuleContents,TOKEN_TREE__0,TOKEN_TREE__1,TOKEN_TREE__2,TOKEN_TREE__3,TOKEN_TREE__4,TOKEN_TREE__5,TOKEN_TREE__6,TOKEN_TREE__2__0,TOKEN_TREE__2__1,TOKEN_TREE__4__0,TOKEN_TREE__4__1,TOKEN_TREE__6__0,TOKEN_TREE__6__1,Expr__0,Expr__1,Expr__2,Expr__3,Expr__4,Expr__5,Expr__6,Expr__7,Expr__8,Expr__9,Expr__10,Expr__11,Expr__12,Expr__13,Expr__14,Expr__15,Expr__1__0,Expr__2__0,Expr__2__1,Expr__3__0,Expr__4__0,Expr__5__0,Expr__5__1,Expr__6__0,Expr__6__1,Expr__7__0,Expr__7__1,Expr__8__0,Expr__8__1,Expr__9__0,Expr__9__1,Expr__9__2,Expr__9__2__0,Expr__9__2__1,Expr__9__2__2,Expr__9__2__1__0,Expr__10__0,Expr__10__1,Expr__11__0,Expr__11__1,Expr__11__2,Expr__11__2__0,Expr__11__2__1,Expr__11__2__2,Expr__11__2__1__0,Expr__12__0,Expr__12__1,Expr__12__2,Expr__12__3,Expr__12__2__0,Expr__12__2__1,Expr__12__2__2,Expr__12__2__1__0,Expr__13__0,Expr__13__1,Expr__13__2,Expr__13__3,Expr__13__4,Expr__13__2__0,Expr__13__2__1,Expr__13__2__2,Expr__13__2__1__0,Expr__14__0,Expr__15__0,ModuleContents__0,ModuleContents__1,ModuleContents__1__0,ModuleContents__1__1,ModuleContents__1__2,}impl CodeLabel for _C { + fn enclosing_fn(self) -> Self { + match self {_C::IDENT => _C::IDENT,_C::PUNCT => _C::PUNCT,_C::LITERAL => _C::LITERAL,_C::TOKEN_TREE => _C::TOKEN_TREE,_C::LIFETIME => _C::LIFETIME,_C::Expr => _C::Expr,_C::ModuleContents => _C::ModuleContents,_C::TOKEN_TREE__0 => _C::TOKEN_TREE,_C::TOKEN_TREE__1 => _C::TOKEN_TREE,_C::TOKEN_TREE__2 => _C::TOKEN_TREE__2,_C::TOKEN_TREE__3 => _C::TOKEN_TREE,_C::TOKEN_TREE__4 => _C::TOKEN_TREE__4,_C::TOKEN_TREE__5 => _C::TOKEN_TREE,_C::TOKEN_TREE__6 => _C::TOKEN_TREE__6,_C::TOKEN_TREE__2__0 => _C::TOKEN_TREE__2,_C::TOKEN_TREE__2__1 => _C::TOKEN_TREE__2,_C::TOKEN_TREE__4__0 => _C::TOKEN_TREE__4,_C::TOKEN_TREE__4__1 => _C::TOKEN_TREE__4,_C::TOKEN_TREE__6__0 => _C::TOKEN_TREE__6,_C::TOKEN_TREE__6__1 => _C::TOKEN_TREE__6,_C::Expr__0 => _C::Expr,_C::Expr__1 => _C::Expr__1,_C::Expr__2 => _C::Expr__2,_C::Expr__3 => _C::Expr__3,_C::Expr__4 => _C::Expr__4,_C::Expr__5 => _C::Expr__5,_C::Expr__6 => _C::Expr__6,_C::Expr__7 => _C::Expr__7,_C::Expr__8 => _C::Expr__8,_C::Expr__9 => _C::Expr__9,_C::Expr__10 => _C::Expr__10,_C::Expr__11 => _C::Expr__11,_C::Expr__12 => _C::Expr__12,_C::Expr__13 => _C::Expr__13,_C::Expr__14 => _C::Expr__14,_C::Expr__15 => _C::Expr__15,_C::Expr__1__0 => _C::Expr__1,_C::Expr__2__0 => _C::Expr__2,_C::Expr__2__1 => _C::Expr__2,_C::Expr__3__0 => _C::Expr__3,_C::Expr__4__0 => _C::Expr__4,_C::Expr__5__0 => _C::Expr__5,_C::Expr__5__1 => _C::Expr__5,_C::Expr__6__0 => _C::Expr__6,_C::Expr__6__1 => _C::Expr__6,_C::Expr__7__0 => _C::Expr__7,_C::Expr__7__1 => _C::Expr__7,_C::Expr__8__0 => _C::Expr__8,_C::Expr__8__1 => _C::Expr__8,_C::Expr__9__0 => _C::Expr__9,_C::Expr__9__1 => _C::Expr__9,_C::Expr__9__2 => _C::Expr__9__2,_C::Expr__9__2__0 => _C::Expr__9__2,_C::Expr__9__2__1 => _C::Expr__9__2__1,_C::Expr__9__2__2 => _C::Expr__9__2,_C::Expr__9__2__1__0 => _C::Expr__9__2__1,_C::Expr__10__0 => _C::Expr__10,_C::Expr__10__1 => _C::Expr__10,_C::Expr__11__0 => _C::Expr__11,_C::Expr__11__1 => _C::Expr__11,_C::Expr__11__2 => _C::Expr__11__2,_C::Expr__11__2__0 => _C::Expr__11__2,_C::Expr__11__2__1 => _C::Expr__11__2__1,_C::Expr__11__2__2 => _C::Expr__11__2,_C::Expr__11__2__1__0 => _C::Expr__11__2__1,_C::Expr__12__0 => _C::Expr__12,_C::Expr__12__1 => _C::Expr__12,_C::Expr__12__2 => _C::Expr__12__2,_C::Expr__12__3 => _C::Expr__12,_C::Expr__12__2__0 => _C::Expr__12__2,_C::Expr__12__2__1 => _C::Expr__12__2__1,_C::Expr__12__2__2 => _C::Expr__12__2,_C::Expr__12__2__1__0 => _C::Expr__12__2__1,_C::Expr__13__0 => _C::Expr__13,_C::Expr__13__1 => _C::Expr__13,_C::Expr__13__2 => _C::Expr__13__2,_C::Expr__13__3 => _C::Expr__13,_C::Expr__13__4 => _C::Expr__13,_C::Expr__13__2__0 => _C::Expr__13__2,_C::Expr__13__2__1 => _C::Expr__13__2__1,_C::Expr__13__2__2 => _C::Expr__13__2,_C::Expr__13__2__1__0 => _C::Expr__13__2__1,_C::Expr__14__0 => _C::Expr__14,_C::Expr__15__0 => _C::Expr__15,_C::ModuleContents__0 => _C::ModuleContents,_C::ModuleContents__1 => _C::ModuleContents__1,_C::ModuleContents__1__0 => _C::ModuleContents__1,_C::ModuleContents__1__1 => _C::ModuleContents__1,_C::ModuleContents__1__2 => _C::ModuleContents__1,} } } \ No newline at end of file