├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md ├── build ├── src │ ├── libparser.a │ └── parserCLI └── tests │ └── parserTestSuite ├── genParser.bash ├── src ├── CMakeLists.txt ├── cli │ └── parserCLI.cc ├── parser │ ├── Parser.h │ ├── Parser.ih │ ├── Parserbase.h │ ├── grammar.y │ └── parse.cc └── scanner │ ├── Scanner.h │ ├── Scanner.ih │ ├── Scannerbase.h │ ├── lex.cc │ └── lexer ├── starFieldGraphDb.jpg └── tests ├── CMakeLists.txt └── ParserTestSuite.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | CMakeCache.txt 2 | CMakeFiles 3 | CMakeScripts 4 | Testing 5 | Makefile 6 | cmake_install.cmake 7 | install_manifest.txt 8 | compile_commands.json 9 | CTestTestfile.cmake 10 | nbproject 11 | build 12 | .vscode -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 2.8) 2 | project (embeddedCypher) 3 | 4 | set(CMAKE_CXX_STANDARD 11) 5 | 6 | add_subdirectory (src) 7 | add_subdirectory (tests) 8 | enable_testing () 9 | add_test (NAME parserTestSuite COMMAND parserTestSuite) 10 | add_dependencies(parserTestSuite parser) 11 | add_dependencies(parserCLI parser) 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2017, expertcompsci 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Graph databases are cool](starFieldGraphDb.jpg) 2 | # embeddedCypher 3 | A portable, in-memory, persistant graph DBMS that implements the [openCypher](http://www.opencypher.org) query language. 4 | 5 | ### Hypothesis 6 | As graph database systems are adopted more developers will feel comfortable using a graph query language. Much as SQL systems found adoption on small devices ([SQLite](http://sqlite.org) is the most installed DBMS in the world) devs could use graph databases on small devices with greater ability to represent and explore complex relationships using an easy to learn/use graph query language. An example openCypher query: 7 | 8 | ```MATCH (embeddedCypher)-[:implements]->(openCypher) RETURN *``` 9 | 10 | ### Examples 11 | For an example of a more capable device implementation, consider: Android via NDK where a KV store can treat SD storage as it would a disk or use faster Android "internal" memory efficiently as contiguous RAM. On the other end of the spectrum there exist processors available for around 1 USD that have C/C++ development tools available. The goal is ubiquitous:relaxed:deployment. 12 | 13 | ### How 14 | While experimentation is encouraged now, an emphasis will be put on portability to the point of making embedding possible by abstracting byte order and solving performance issues etc. Unit and End To End testing will drive development. 15 | 16 | Some major tools and components: 17 | * E2E and Unit testing: **CTest, Google GTest** 18 | * UnQLite: For the Key/Value backing store 19 | * Bisonc++: Parser 20 | * Flexc++: Lexical Scanner 21 | * Cmake/Clang/LLVM: A Reference build system 22 | 23 | __Note__: 24 | bisonc++ and flexc++ are programs used to generate the parser and lexical scanner respectively. They generate the files identified below: 25 | 26 | bisonc++: 27 | * parse.cc 28 | * Parser.h - Not overwritten by bisonc++. Contains essential edits. 29 | * Parser.ih 30 | * Parserbase.h 31 | 32 | flexc++: 33 | * lex.cc 34 | * Scanner.h 35 | * Scanner.ih - Not overwritten by flexc++. Contains essential edits. 36 | * Scannerbase.h 37 | 38 | The Bash script genParser.bash invokes bisonc++ and flexc++ for generation of the parser and scanner but is only needed if updates are made to the files parser/grammar.y and scanner/lexer. 39 | -------------------------------------------------------------------------------- /build/src/libparser.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/expertcompsci/embeddedCypher/e2734d9b59b8baa6ed5f725dfe5b7dc3df959e6f/build/src/libparser.a -------------------------------------------------------------------------------- /build/src/parserCLI: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/expertcompsci/embeddedCypher/e2734d9b59b8baa6ed5f725dfe5b7dc3df959e6f/build/src/parserCLI -------------------------------------------------------------------------------- /build/tests/parserTestSuite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/expertcompsci/embeddedCypher/e2734d9b59b8baa6ed5f725dfe5b7dc3df959e6f/build/tests/parserTestSuite -------------------------------------------------------------------------------- /genParser.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # BSD 3-Clause License 3 | # 4 | # Copyright (c) 2017, expertcompsci 5 | # All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions are met: 9 | # 10 | # * Redistributions of source code must retain the above copyright notice, this 11 | # list of conditions and the following disclaimer. 12 | # 13 | # * Redistributions in binary form must reproduce the above copyright notice, 14 | # this list of conditions and the following disclaimer in the documentation 15 | # and/or other materials provided with the distribution. 16 | # 17 | # * Neither the name of the copyright holder nor the names of its 18 | # contributors may be used to endorse or promote products derived from 19 | # this software without specific prior written permission. 20 | # 21 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 25 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | cd ./src/parser 32 | rm Parserbase.h 33 | bisonc++ grammar.y 34 | cd ../.. 35 | cd ./src/scanner 36 | flexc++ lexer 37 | cd ../.. 38 | ls -la ./src/scanner/lex.cc 39 | ls -la ./src/parser/parse.cc 40 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_CXX_STANDARD 11) 2 | 3 | include_directories(parser scanner cli) 4 | add_library(parser scanner/lex.cc parser/parse.cc) 5 | target_include_directories (parser PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/parser) 6 | 7 | add_executable(parserCLI cli/parserCLI.cc) 8 | target_link_libraries(parserCLI LINK_PUBLIC parser) 9 | -------------------------------------------------------------------------------- /src/cli/parserCLI.cc: -------------------------------------------------------------------------------- 1 | /* 2 | BSD 3-Clause License 3 | 4 | Copyright (c) 2017, expertcompsci 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | * Neither the name of the copyright holder nor the names of its 18 | contributors may be used to endorse or promote products derived from 19 | this software without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 25 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | #include 33 | 34 | #include "../parser/Parser.h" 35 | 36 | int main(int argc, char **argv) 37 | { 38 | int ret = 0; 39 | if(argc > 1) { 40 | std::ostringstream oss; 41 | std::istringstream iss; 42 | iss.str(argv[1]); 43 | 44 | Parser parser(iss, oss); 45 | 46 | ret = parser.parse(); // Returns 1 on error 47 | std::cout << oss.str(); 48 | if(ret == 0){ 49 | std::cout << "main.cc: Parsing completed successfully."; 50 | } else { 51 | std::cout << "main.cc: parse() returned the error flag."; 52 | } 53 | } else { 54 | std::cout << "Usage: parserCLI 'string to parse' "; 55 | ret = 2; 56 | } 57 | return ret; 58 | } 59 | -------------------------------------------------------------------------------- /src/parser/Parser.h: -------------------------------------------------------------------------------- 1 | /* 2 | BSD 3-Clause License 3 | 4 | Copyright (c) 2017, expertcompsci 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | * Neither the name of the copyright holder nor the names of its 18 | contributors may be used to endorse or promote products derived from 19 | this software without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 25 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | 33 | #ifndef Parser_h_included 34 | #define Parser_h_included 35 | 36 | // $insert baseclass 37 | #include "Parserbase.h" 38 | // $insert scanner.h 39 | #include "../scanner/Scanner.h" 40 | 41 | 42 | #undef Parser 43 | class Parser: public ParserBase 44 | { 45 | // $insert scannerobject 46 | Scanner d_scanner; 47 | 48 | public: 49 | 50 | Parser(std::istream &in, std::ostream &out) : d_scanner(in, out) {} 51 | 52 | int parse(); 53 | private: 54 | 55 | void error(char const *msg); // called on (syntax) errors 56 | int lex(); // returns the next token from the 57 | // lexical scanner. 58 | void print(); // use, e.g., d_token, d_loc 59 | 60 | // support functions for parse(): 61 | void executeAction(int ruleNr); 62 | void errorRecovery(); 63 | int lookup(bool recovery); 64 | void nextToken(); 65 | void print__(); 66 | void exceptionHandler__(std::exception const &exc); 67 | }; 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /src/parser/Parser.ih: -------------------------------------------------------------------------------- 1 | // Generated by Bisonc++ V4.13.01 on Thu, 17 Aug 2017 21:45:41 -0400 2 | 3 | // Include this file in the sources of the class Parser. 4 | 5 | // $insert class.h 6 | #include "Parser.h" 7 | 8 | 9 | inline void Parser::error(char const *msg) 10 | { 11 | std::cerr << msg << '\n'; 12 | } 13 | 14 | // $insert lex 15 | inline int Parser::lex() 16 | { 17 | return d_scanner.lex(); 18 | } 19 | 20 | inline void Parser::print() 21 | { 22 | print__(); // displays tokens if --print was specified 23 | } 24 | 25 | inline void Parser::exceptionHandler__(std::exception const &exc) 26 | { 27 | throw; // re-implement to handle exceptions thrown by actions 28 | } 29 | 30 | 31 | // Add here includes that are only required for the compilation 32 | // of Parser's sources. 33 | 34 | 35 | 36 | // UN-comment the next using-declaration if you want to use 37 | // int Parser's sources symbols from the namespace std without 38 | // specifying std:: 39 | 40 | //using namespace std; 41 | -------------------------------------------------------------------------------- /src/parser/Parserbase.h: -------------------------------------------------------------------------------- 1 | // Generated by Bisonc++ V4.13.01 on Sat, 26 Aug 2017 21:58:52 -0400 2 | 3 | #ifndef ParserBase_h_included 4 | #define ParserBase_h_included 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | // $insert debugincludes 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace // anonymous 18 | { 19 | struct PI__; 20 | } 21 | 22 | 23 | 24 | class ParserBase 25 | { 26 | public: 27 | // $insert tokens 28 | 29 | // Symbolic tokens: 30 | enum Tokens__ 31 | { 32 | ALL = 257, 33 | UNION, 34 | MATCH, 35 | CREATE, 36 | RETURN, 37 | AS, 38 | DISTINCT, 39 | WHERE, 40 | ORDER, 41 | BY, 42 | ASC, 43 | DESC, 44 | LIMIT, 45 | AND, 46 | OR, 47 | TRUE, 48 | FALSE, 49 | IDENTIFIER, 50 | FLOAT, 51 | INTEGER, 52 | STRING, 53 | COMMA, 54 | LEFT_PAREN, 55 | RIGHT_PAREN, 56 | LEFT_BRACKET, 57 | RIGHT_BRACKET, 58 | LEFT_CURLY_BRACKET, 59 | RIGHT_CURLY_BRACKET, 60 | GE, 61 | LE, 62 | EDGE, 63 | LEFT_EDGE, 64 | RIGHT_EDGE, 65 | SHAFT, 66 | LEFT_ARROW, 67 | RIGHT_ARROW, 68 | GT, 69 | LT, 70 | NE, 71 | EQ, 72 | COLON, 73 | SEMICOLON, 74 | DOT, 75 | ASTERISK, 76 | OPTIONAL, 77 | DOLLAR, 78 | BAR, 79 | }; 80 | 81 | // $insert STYPE 82 | typedef int STYPE__; 83 | 84 | private: 85 | int d_stackIdx__; 86 | std::vector d_stateStack__; 87 | std::vector d_valueStack__; 88 | 89 | protected: 90 | enum Return__ 91 | { 92 | PARSE_ACCEPT__ = 0, // values used as parse()'s return values 93 | PARSE_ABORT__ = 1 94 | }; 95 | enum ErrorRecovery__ 96 | { 97 | DEFAULT_RECOVERY_MODE__, 98 | UNEXPECTED_TOKEN__, 99 | }; 100 | bool d_debug__; 101 | size_t d_nErrors__; 102 | size_t d_requiredTokens__; 103 | size_t d_acceptedTokens__; 104 | int d_token__; 105 | int d_nextToken__; 106 | size_t d_state__; 107 | STYPE__ *d_vsp__; 108 | STYPE__ d_val__; 109 | STYPE__ d_nextVal__; 110 | 111 | ParserBase(); 112 | 113 | // $insert debugdecl 114 | static std::ostringstream s_out__; 115 | 116 | std::string symbol__(int value) const; 117 | std::string stype__(char const *pre, STYPE__ const &semVal, 118 | char const *post = "") const; 119 | static std::ostream &dflush__(std::ostream &out); 120 | void ABORT() const; 121 | void ACCEPT() const; 122 | void ERROR() const; 123 | void clearin(); 124 | bool debug() const; 125 | void pop__(size_t count = 1); 126 | void push__(size_t nextState); 127 | void popToken__(); 128 | void pushToken__(int token); 129 | void reduce__(PI__ const &productionInfo); 130 | void errorVerbose__(); 131 | size_t top__() const; 132 | 133 | public: 134 | void setDebug(bool mode); 135 | }; 136 | 137 | inline bool ParserBase::debug() const 138 | { 139 | return d_debug__; 140 | } 141 | 142 | inline void ParserBase::setDebug(bool mode) 143 | { 144 | d_debug__ = mode; 145 | } 146 | 147 | inline void ParserBase::ABORT() const 148 | { 149 | throw PARSE_ABORT__; 150 | } 151 | 152 | inline void ParserBase::ACCEPT() const 153 | { 154 | throw PARSE_ACCEPT__; 155 | } 156 | 157 | inline void ParserBase::ERROR() const 158 | { 159 | throw UNEXPECTED_TOKEN__; 160 | } 161 | 162 | 163 | // As a convenience, when including ParserBase.h its symbols are available as 164 | // symbols in the class Parser, too. 165 | #define Parser ParserBase 166 | 167 | 168 | #endif 169 | 170 | 171 | -------------------------------------------------------------------------------- /src/parser/grammar.y: -------------------------------------------------------------------------------- 1 | /* 2 | BSD 3-Clause License 3 | 4 | Copyright (c) 2017, expertcompsci 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | * Neither the name of the copyright holder nor the names of its 18 | contributors may be used to endorse or promote products derived from 19 | this software without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 25 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | %scanner ../scanner/Scanner.h 33 | %scanner-token-function d_scanner.lex() 34 | 35 | %token ALL 36 | %token UNION 37 | %token MATCH 38 | %token CREATE 39 | %token RETURN 40 | %token AS 41 | %token DISTINCT 42 | %token WHERE 43 | %token ORDER 44 | %token BY 45 | %token ASC 46 | %token DESC 47 | %token LIMIT 48 | %token AND 49 | %token OR 50 | %token TRUE 51 | %token FALSE 52 | %token IDENTIFIER 53 | %token FLOAT 54 | %token INTEGER 55 | %token STRING 56 | %token COMMA 57 | %token LEFT_PAREN 58 | %token RIGHT_PAREN 59 | %token LEFT_BRACKET 60 | %token RIGHT_BRACKET 61 | %token LEFT_CURLY_BRACKET 62 | %token RIGHT_CURLY_BRACKET 63 | %token GE 64 | %token LE 65 | %token EDGE 66 | %token LEFT_EDGE 67 | %token RIGHT_EDGE 68 | %token SHAFT 69 | %token LEFT_ARROW 70 | %token RIGHT_ARROW 71 | %token GT 72 | %token LT 73 | %token NE 74 | %token EQ 75 | %token COLON 76 | %token SEMICOLON 77 | %token DOT 78 | %token ASTERISK 79 | %token OPTIONAL 80 | %token DOLLAR 81 | %token BAR 82 | 83 | %print-tokens 84 | 85 | %start start_rule 86 | 87 | %% 88 | 89 | start_rule: cypher; 90 | 91 | cypher: 92 | statement 93 | { std::cout << " cypher: statement \n"; } 94 | | 95 | statement SEMICOLON 96 | ; 97 | 98 | statement: query ; 99 | 100 | query: 101 | regular_query 102 | { std::cout << "regular_query\n"; } 103 | //| 104 | // standalone_call 105 | ; 106 | 107 | regular_query: single_query 108 | // TODO: union 109 | ; 110 | 111 | single_query: 112 | single_part_query 113 | //| 114 | // multi_part_query 115 | ; 116 | 117 | single_part_query: 118 | read_only_end 119 | | 120 | read_update_end 121 | | 122 | updating_end 123 | ; 124 | 125 | read_only_end: read_part return; 126 | 127 | read_part: 128 | // empty 129 | | 130 | reading_clause 131 | ; 132 | 133 | reading_clause: 134 | match 135 | | 136 | reading_clause match 137 | // TODO: Unwind and InQueryCall 138 | ; 139 | 140 | updating_clause: 141 | create 142 | | 143 | updating_clause create 144 | // TODO: merge, delete, set, remove 145 | ; 146 | 147 | read_update_end: 148 | reading_clause updating_clause 149 | | 150 | reading_clause updating_clause return 151 | ; 152 | 153 | updating_end: 154 | create 155 | | 156 | // TODO: merge 157 | | 158 | create updating_clause opt_return 159 | ; 160 | 161 | opt_return: 162 | // empty 163 | | 164 | return 165 | ; 166 | 167 | return: 168 | RETURN return_body 169 | | 170 | RETURN DISTINCT return_body 171 | ; 172 | 173 | return_body: 174 | ASTERISK 175 | | 176 | expression_list 177 | ; 178 | 179 | variable: IDENTIFIER; 180 | 181 | // TODO: order_by, skip, limit, starts with, contains, not etc. 182 | expression_list: 183 | expression 184 | | 185 | expression AS variable 186 | | 187 | expression_list COMMA expression 188 | | 189 | expression_list COMMA expression AS variable 190 | ; 191 | 192 | node_name: 193 | IDENTIFIER 194 | ; 195 | 196 | opt_node_name: 197 | // empty 198 | | 199 | node_name 200 | ; 201 | 202 | relationship_name: 203 | IDENTIFIER 204 | ; 205 | 206 | opt_relationship_name: 207 | // empty 208 | | 209 | relationship_name 210 | ; 211 | 212 | opt_variable_eq: 213 | // empty 214 | | 215 | IDENTIFIER EQ 216 | ; 217 | 218 | opt_where: 219 | // empty 220 | | 221 | WHERE expression 222 | ; 223 | 224 | match: 225 | MATCH pattern opt_where 226 | | 227 | OPTIONAL MATCH pattern opt_where 228 | ; 229 | 230 | create: CREATE pattern; 231 | 232 | pattern: 233 | opt_variable_eq pattern_element 234 | | 235 | pattern COMMA opt_variable_eq pattern_element 236 | ; 237 | 238 | pattern_element: 239 | node_pattern 240 | | 241 | node_pattern EDGE pattern_element 242 | | 243 | node_pattern RIGHT_EDGE pattern_element 244 | | 245 | node_pattern LEFT_EDGE pattern_element 246 | | 247 | node_pattern SHAFT relationship_pattern SHAFT pattern_element 248 | | 249 | node_pattern SHAFT relationship_pattern RIGHT_ARROW pattern_element 250 | | 251 | node_pattern LEFT_ARROW relationship_pattern SHAFT pattern_element 252 | ; 253 | 254 | node_pattern: 255 | LEFT_PAREN opt_node_detail RIGHT_PAREN 256 | ; 257 | 258 | opt_node_detail: 259 | // empty 260 | | 261 | node_detail 262 | ; 263 | 264 | node_detail: 265 | opt_node_name opt_map_literal 266 | | 267 | opt_node_name node_labels opt_map_literal 268 | ; 269 | 270 | node_labels: 271 | COLON IDENTIFIER 272 | | 273 | node_labels COLON IDENTIFIER 274 | ; 275 | 276 | relationship_pattern: 277 | relationship_detail 278 | ; 279 | 280 | relationship_label_pair: 281 | COLON IDENTIFIER 282 | | 283 | IDENTIFIER 284 | ; 285 | 286 | relationship_label: 287 | relationship_label_pair 288 | | 289 | relationship_label BAR relationship_label_pair 290 | ; 291 | 292 | opt_relationship_label: 293 | // empty 294 | | 295 | relationship_label 296 | ; 297 | 298 | relationship_detail: 299 | LEFT_BRACKET 300 | opt_relationship_name 301 | opt_relationship_label 302 | RIGHT_BRACKET 303 | ; 304 | 305 | 306 | opt_map_literal: 307 | // empty 308 | | 309 | map_literal 310 | ; 311 | 312 | property_key_name: IDENTIFIER; 313 | 314 | property_key_value_pair: property_key_name COLON expression; 315 | 316 | property_key_value_pairs: 317 | property_key_value_pair 318 | | 319 | property_key_value_pairs COMMA property_key_value_pair 320 | ; 321 | 322 | map_literal: LEFT_CURLY_BRACKET property_key_value_pairs RIGHT_CURLY_BRACKET; 323 | 324 | expression: IDENTIFIER; 325 | 326 | //parameter: 327 | // DOLLAR IDENTIFIER 328 | //| 329 | // DOLLAR INTEGER 330 | //; 331 | -------------------------------------------------------------------------------- /src/parser/parse.cc: -------------------------------------------------------------------------------- 1 | // Generated by Bisonc++ V4.13.01 on Sat, 26 Aug 2017 21:58:52 -0400 2 | 3 | // $insert class.ih 4 | #include "Parser.ih" 5 | 6 | // The FIRST element of SR arrays shown below uses `d_type', defining the 7 | // state's type, and `d_lastIdx' containing the last element's index. If 8 | // d_lastIdx contains the REQ_TOKEN bitflag (see below) then the state needs 9 | // a token: if in this state d_token__ is _UNDETERMINED_, nextToken() will be 10 | // called 11 | 12 | // The LAST element of SR arrays uses `d_token' containing the last retrieved 13 | // token to speed up the (linear) seach. Except for the first element of SR 14 | // arrays, the field `d_action' is used to determine what to do next. If 15 | // positive, it represents the next state (used with SHIFT); if zero, it 16 | // indicates `ACCEPT', if negative, -d_action represents the number of the 17 | // rule to reduce to. 18 | 19 | // `lookup()' tries to find d_token__ in the current SR array. If it fails, and 20 | // there is no default reduction UNEXPECTED_TOKEN__ is thrown, which is then 21 | // caught by the error-recovery function. 22 | 23 | // The error-recovery function will pop elements off the stack until a state 24 | // having bit flag ERR_ITEM is found. This state has a transition on _error_ 25 | // which is applied. In this _error_ state, while the current token is not a 26 | // proper continuation, new tokens are obtained by nextToken(). If such a 27 | // token is found, error recovery is successful and the token is 28 | // handled according to the error state's SR table and parsing continues. 29 | // During error recovery semantic actions are ignored. 30 | 31 | // A state flagged with the DEF_RED flag will perform a default 32 | // reduction if no other continuations are available for the current token. 33 | 34 | // The ACCEPT STATE never shows a default reduction: when it is reached the 35 | // parser returns ACCEPT(). During the grammar 36 | // analysis phase a default reduction may have been defined, but it is 37 | // removed during the state-definition phase. 38 | 39 | // So: 40 | // s_x[] = 41 | // { 42 | // [_field_1_] [_field_2_] 43 | // 44 | // First element: {state-type, idx of last element}, 45 | // Other elements: {required token, action to perform}, 46 | // ( < 0: reduce, 47 | // 0: ACCEPT, 48 | // > 0: next state) 49 | // Last element: {set to d_token__, action to perform} 50 | // } 51 | 52 | // When the --thread-safe option is specified, all static data are defined as 53 | // const. If --thread-safe is not provided, the state-tables are not defined 54 | // as const, since the lookup() function below will modify them 55 | 56 | // $insert debugincludes 57 | #include 58 | #include 59 | #include 60 | #include 61 | #include 62 | 63 | namespace // anonymous 64 | { 65 | char const author[] = "Frank B. Brokken (f.b.brokken@rug.nl)"; 66 | 67 | enum 68 | { 69 | STACK_EXPANSION = 5 // size to expand the state-stack with when 70 | // full 71 | }; 72 | 73 | enum ReservedTokens 74 | { 75 | PARSE_ACCEPT = 0, // `ACCEPT' TRANSITION 76 | _UNDETERMINED_ = -2, 77 | _EOF_ = -1, 78 | _error_ = 256 79 | }; 80 | enum StateType // modify statetype/data.cc when this enum changes 81 | { 82 | NORMAL, 83 | ERR_ITEM, 84 | REQ_TOKEN, 85 | ERR_REQ, // ERR_ITEM | REQ_TOKEN 86 | DEF_RED, // state having default reduction 87 | ERR_DEF, // ERR_ITEM | DEF_RED 88 | REQ_DEF, // REQ_TOKEN | DEF_RED 89 | ERR_REQ_DEF // ERR_ITEM | REQ_TOKEN | DEF_RED 90 | }; 91 | struct PI__ // Production Info 92 | { 93 | size_t d_nonTerm; // identification number of this production's 94 | // non-terminal 95 | size_t d_size; // number of elements in this production 96 | }; 97 | 98 | struct SR__ // Shift Reduce info, see its description above 99 | { 100 | union 101 | { 102 | int _field_1_; // initializer, allowing initializations 103 | // of the SR s_[] arrays 104 | int d_type; 105 | int d_token; 106 | }; 107 | union 108 | { 109 | int _field_2_; 110 | 111 | int d_lastIdx; // if negative, the state uses SHIFT 112 | int d_action; // may be negative (reduce), 113 | // postive (shift), or 0 (accept) 114 | size_t d_errorState; // used with Error states 115 | }; 116 | }; 117 | 118 | // $insert staticdata 119 | 120 | // Productions Info Records: 121 | PI__ const s_productionInfo[] = 122 | { 123 | {0, 0}, // not used: reduction values are negative 124 | {304, 1}, // 1: start_rule -> cypher 125 | {305, 1}, // 2: cypher -> statement 126 | {305, 2}, // 3: cypher (SEMICOLON) -> statement SEMICOLON 127 | {306, 1}, // 4: statement -> query 128 | {307, 1}, // 5: query -> regular_query 129 | {308, 1}, // 6: regular_query -> single_query 130 | {309, 1}, // 7: single_query -> single_part_query 131 | {310, 1}, // 8: single_part_query -> read_only_end 132 | {310, 1}, // 9: single_part_query -> read_update_end 133 | {310, 1}, // 10: single_part_query -> updating_end 134 | {311, 2}, // 11: read_only_end -> read_part return 135 | {314, 0}, // 12: read_part -> 136 | {314, 1}, // 13: read_part -> reading_clause 137 | {316, 1}, // 14: reading_clause -> match 138 | {316, 2}, // 15: reading_clause -> reading_clause match 139 | {318, 1}, // 16: updating_clause -> create 140 | {318, 2}, // 17: updating_clause -> updating_clause create 141 | {312, 2}, // 18: read_update_end -> reading_clause updating_clause 142 | {312, 3}, // 19: read_update_end -> reading_clause updating_clause return 143 | {313, 1}, // 20: updating_end -> create 144 | {313, 0}, // 21: updating_end -> 145 | {313, 3}, // 22: updating_end -> create updating_clause opt_return 146 | {320, 0}, // 23: opt_return -> 147 | {320, 1}, // 24: opt_return -> return 148 | {315, 2}, // 25: return (RETURN) -> RETURN return_body 149 | {315, 3}, // 26: return (RETURN) -> RETURN DISTINCT return_body 150 | {321, 1}, // 27: return_body (ASTERISK) -> ASTERISK 151 | {321, 1}, // 28: return_body -> expression_list 152 | {323, 1}, // 29: variable (IDENTIFIER) -> IDENTIFIER 153 | {322, 1}, // 30: expression_list -> expression 154 | {322, 3}, // 31: expression_list (AS) -> expression AS variable 155 | {322, 3}, // 32: expression_list (COMMA) -> expression_list COMMA expression 156 | {322, 5}, // 33: expression_list (COMMA) -> expression_list COMMA expression AS variable 157 | {325, 1}, // 34: node_name (IDENTIFIER) -> IDENTIFIER 158 | {326, 0}, // 35: opt_node_name -> 159 | {326, 1}, // 36: opt_node_name -> node_name 160 | {327, 1}, // 37: relationship_name (IDENTIFIER) -> IDENTIFIER 161 | {328, 0}, // 38: opt_relationship_name -> 162 | {328, 1}, // 39: opt_relationship_name -> relationship_name 163 | {329, 0}, // 40: opt_variable_eq -> 164 | {329, 2}, // 41: opt_variable_eq (IDENTIFIER) -> IDENTIFIER EQ 165 | {330, 0}, // 42: opt_where -> 166 | {330, 2}, // 43: opt_where (WHERE) -> WHERE expression 167 | {317, 3}, // 44: match (MATCH) -> MATCH pattern opt_where 168 | {317, 4}, // 45: match (OPTIONAL) -> OPTIONAL MATCH pattern opt_where 169 | {319, 2}, // 46: create (CREATE) -> CREATE pattern 170 | {331, 2}, // 47: pattern -> opt_variable_eq pattern_element 171 | {331, 4}, // 48: pattern (COMMA) -> pattern COMMA opt_variable_eq pattern_element 172 | {332, 1}, // 49: pattern_element -> node_pattern 173 | {332, 3}, // 50: pattern_element (EDGE) -> node_pattern EDGE pattern_element 174 | {332, 3}, // 51: pattern_element (RIGHT_EDGE) -> node_pattern RIGHT_EDGE pattern_element 175 | {332, 3}, // 52: pattern_element (LEFT_EDGE) -> node_pattern LEFT_EDGE pattern_element 176 | {332, 5}, // 53: pattern_element (SHAFT) -> node_pattern SHAFT relationship_pattern SHAFT pattern_element 177 | {332, 5}, // 54: pattern_element (SHAFT) -> node_pattern SHAFT relationship_pattern RIGHT_ARROW pattern_element 178 | {332, 5}, // 55: pattern_element (LEFT_ARROW) -> node_pattern LEFT_ARROW relationship_pattern SHAFT pattern_element 179 | {333, 3}, // 56: node_pattern (LEFT_PAREN) -> LEFT_PAREN opt_node_detail RIGHT_PAREN 180 | {335, 0}, // 57: opt_node_detail -> 181 | {335, 1}, // 58: opt_node_detail -> node_detail 182 | {336, 2}, // 59: node_detail -> opt_node_name opt_map_literal 183 | {336, 3}, // 60: node_detail -> opt_node_name node_labels opt_map_literal 184 | {338, 2}, // 61: node_labels (COLON) -> COLON IDENTIFIER 185 | {338, 3}, // 62: node_labels (COLON) -> node_labels COLON IDENTIFIER 186 | {334, 1}, // 63: relationship_pattern -> relationship_detail 187 | {340, 2}, // 64: relationship_label_pair (COLON) -> COLON IDENTIFIER 188 | {340, 1}, // 65: relationship_label_pair (IDENTIFIER) -> IDENTIFIER 189 | {341, 1}, // 66: relationship_label -> relationship_label_pair 190 | {341, 3}, // 67: relationship_label (BAR) -> relationship_label BAR relationship_label_pair 191 | {342, 0}, // 68: opt_relationship_label -> 192 | {342, 1}, // 69: opt_relationship_label -> relationship_label 193 | {339, 4}, // 70: relationship_detail (LEFT_BRACKET) -> LEFT_BRACKET opt_relationship_name opt_relationship_label RIGHT_BRACKET 194 | {337, 0}, // 71: opt_map_literal -> 195 | {337, 1}, // 72: opt_map_literal -> map_literal 196 | {344, 1}, // 73: property_key_name (IDENTIFIER) -> IDENTIFIER 197 | {345, 3}, // 74: property_key_value_pair (COLON) -> property_key_name COLON expression 198 | {346, 1}, // 75: property_key_value_pairs -> property_key_value_pair 199 | {346, 3}, // 76: property_key_value_pairs (COMMA) -> property_key_value_pairs COMMA property_key_value_pair 200 | {343, 3}, // 77: map_literal (LEFT_CURLY_BRACKET) -> LEFT_CURLY_BRACKET property_key_value_pairs RIGHT_CURLY_BRACKET 201 | {324, 1}, // 78: expression (IDENTIFIER) -> IDENTIFIER 202 | {347, 1}, // 79: start_rule_$ -> start_rule 203 | }; 204 | 205 | // State info and SR__ transitions for each state. 206 | 207 | 208 | SR__ s_0[] = 209 | { 210 | { { REQ_DEF}, { 19} }, 211 | { { 304}, { 1} }, // start_rule 212 | { { 305}, { 2} }, // cypher 213 | { { 306}, { 3} }, // statement 214 | { { 307}, { 4} }, // query 215 | { { 308}, { 5} }, // regular_query 216 | { { 309}, { 6} }, // single_query 217 | { { 310}, { 7} }, // single_part_query 218 | { { 311}, { 8} }, // read_only_end 219 | { { 312}, { 9} }, // read_update_end 220 | { { 313}, { 10} }, // updating_end 221 | { { 314}, { 11} }, // read_part 222 | { { 316}, { 12} }, // reading_clause 223 | { { 319}, { 13} }, // create 224 | { { 317}, { 14} }, // match 225 | { { 260}, { 15} }, // CREATE 226 | { { 259}, { 16} }, // MATCH 227 | { { 301}, { 17} }, // OPTIONAL 228 | { { 298}, { -21} }, // SEMICOLON 229 | { { _EOF_}, { -21} }, // _EOF_ 230 | { { 0}, { -12} }, 231 | }; 232 | 233 | SR__ s_1[] = 234 | { 235 | { { REQ_TOKEN}, { 2} }, 236 | { { _EOF_}, { PARSE_ACCEPT} }, 237 | { { 0}, { 0} }, 238 | }; 239 | 240 | SR__ s_2[] = 241 | { 242 | { { DEF_RED}, { 1} }, 243 | { { 0}, { -1} }, 244 | }; 245 | 246 | SR__ s_3[] = 247 | { 248 | { { REQ_DEF}, { 2} }, 249 | { { 298}, { 18} }, // SEMICOLON 250 | { { 0}, { -2} }, 251 | }; 252 | 253 | SR__ s_4[] = 254 | { 255 | { { DEF_RED}, { 1} }, 256 | { { 0}, { -4} }, 257 | }; 258 | 259 | SR__ s_5[] = 260 | { 261 | { { DEF_RED}, { 1} }, 262 | { { 0}, { -5} }, 263 | }; 264 | 265 | SR__ s_6[] = 266 | { 267 | { { DEF_RED}, { 1} }, 268 | { { 0}, { -6} }, 269 | }; 270 | 271 | SR__ s_7[] = 272 | { 273 | { { DEF_RED}, { 1} }, 274 | { { 0}, { -7} }, 275 | }; 276 | 277 | SR__ s_8[] = 278 | { 279 | { { DEF_RED}, { 1} }, 280 | { { 0}, { -8} }, 281 | }; 282 | 283 | SR__ s_9[] = 284 | { 285 | { { DEF_RED}, { 1} }, 286 | { { 0}, { -9} }, 287 | }; 288 | 289 | SR__ s_10[] = 290 | { 291 | { { DEF_RED}, { 1} }, 292 | { { 0}, { -10} }, 293 | }; 294 | 295 | SR__ s_11[] = 296 | { 297 | { { REQ_TOKEN}, { 3} }, 298 | { { 315}, { 19} }, // return 299 | { { 261}, { 20} }, // RETURN 300 | { { 0}, { 0} }, 301 | }; 302 | 303 | SR__ s_12[] = 304 | { 305 | { { REQ_DEF}, { 7} }, 306 | { { 318}, { 21} }, // updating_clause 307 | { { 317}, { 22} }, // match 308 | { { 319}, { 23} }, // create 309 | { { 259}, { 16} }, // MATCH 310 | { { 301}, { 17} }, // OPTIONAL 311 | { { 260}, { 15} }, // CREATE 312 | { { 0}, { -13} }, 313 | }; 314 | 315 | SR__ s_13[] = 316 | { 317 | { { REQ_DEF}, { 4} }, 318 | { { 318}, { 24} }, // updating_clause 319 | { { 319}, { 23} }, // create 320 | { { 260}, { 15} }, // CREATE 321 | { { 0}, { -20} }, 322 | }; 323 | 324 | SR__ s_14[] = 325 | { 326 | { { DEF_RED}, { 1} }, 327 | { { 0}, { -14} }, 328 | }; 329 | 330 | SR__ s_15[] = 331 | { 332 | { { REQ_DEF}, { 4} }, 333 | { { 331}, { 25} }, // pattern 334 | { { 329}, { 26} }, // opt_variable_eq 335 | { { 274}, { 27} }, // IDENTIFIER 336 | { { 0}, { -40} }, 337 | }; 338 | 339 | SR__ s_16[] = 340 | { 341 | { { REQ_DEF}, { 4} }, 342 | { { 331}, { 28} }, // pattern 343 | { { 329}, { 26} }, // opt_variable_eq 344 | { { 274}, { 27} }, // IDENTIFIER 345 | { { 0}, { -40} }, 346 | }; 347 | 348 | SR__ s_17[] = 349 | { 350 | { { REQ_TOKEN}, { 2} }, 351 | { { 259}, { 29} }, // MATCH 352 | { { 0}, { 0} }, 353 | }; 354 | 355 | SR__ s_18[] = 356 | { 357 | { { DEF_RED}, { 1} }, 358 | { { 0}, { -3} }, 359 | }; 360 | 361 | SR__ s_19[] = 362 | { 363 | { { DEF_RED}, { 1} }, 364 | { { 0}, { -11} }, 365 | }; 366 | 367 | SR__ s_20[] = 368 | { 369 | { { REQ_TOKEN}, { 7} }, 370 | { { 321}, { 30} }, // return_body 371 | { { 263}, { 31} }, // DISTINCT 372 | { { 300}, { 32} }, // ASTERISK 373 | { { 322}, { 33} }, // expression_list 374 | { { 324}, { 34} }, // expression 375 | { { 274}, { 35} }, // IDENTIFIER 376 | { { 0}, { 0} }, 377 | }; 378 | 379 | SR__ s_21[] = 380 | { 381 | { { REQ_DEF}, { 5} }, 382 | { { 315}, { 36} }, // return 383 | { { 319}, { 37} }, // create 384 | { { 261}, { 20} }, // RETURN 385 | { { 260}, { 15} }, // CREATE 386 | { { 0}, { -18} }, 387 | }; 388 | 389 | SR__ s_22[] = 390 | { 391 | { { DEF_RED}, { 1} }, 392 | { { 0}, { -15} }, 393 | }; 394 | 395 | SR__ s_23[] = 396 | { 397 | { { DEF_RED}, { 1} }, 398 | { { 0}, { -16} }, 399 | }; 400 | 401 | SR__ s_24[] = 402 | { 403 | { { REQ_DEF}, { 6} }, 404 | { { 320}, { 38} }, // opt_return 405 | { { 319}, { 37} }, // create 406 | { { 315}, { 39} }, // return 407 | { { 260}, { 15} }, // CREATE 408 | { { 261}, { 20} }, // RETURN 409 | { { 0}, { -23} }, 410 | }; 411 | 412 | SR__ s_25[] = 413 | { 414 | { { REQ_DEF}, { 2} }, 415 | { { 278}, { 40} }, // COMMA 416 | { { 0}, { -46} }, 417 | }; 418 | 419 | SR__ s_26[] = 420 | { 421 | { { REQ_TOKEN}, { 4} }, 422 | { { 332}, { 41} }, // pattern_element 423 | { { 333}, { 42} }, // node_pattern 424 | { { 279}, { 43} }, // LEFT_PAREN 425 | { { 0}, { 0} }, 426 | }; 427 | 428 | SR__ s_27[] = 429 | { 430 | { { REQ_TOKEN}, { 2} }, 431 | { { 296}, { 44} }, // EQ 432 | { { 0}, { 0} }, 433 | }; 434 | 435 | SR__ s_28[] = 436 | { 437 | { { REQ_DEF}, { 4} }, 438 | { { 330}, { 45} }, // opt_where 439 | { { 278}, { 40} }, // COMMA 440 | { { 264}, { 46} }, // WHERE 441 | { { 0}, { -42} }, 442 | }; 443 | 444 | SR__ s_29[] = 445 | { 446 | { { REQ_DEF}, { 4} }, 447 | { { 331}, { 47} }, // pattern 448 | { { 329}, { 26} }, // opt_variable_eq 449 | { { 274}, { 27} }, // IDENTIFIER 450 | { { 0}, { -40} }, 451 | }; 452 | 453 | SR__ s_30[] = 454 | { 455 | { { DEF_RED}, { 1} }, 456 | { { 0}, { -25} }, 457 | }; 458 | 459 | SR__ s_31[] = 460 | { 461 | { { REQ_TOKEN}, { 6} }, 462 | { { 321}, { 48} }, // return_body 463 | { { 300}, { 32} }, // ASTERISK 464 | { { 322}, { 33} }, // expression_list 465 | { { 324}, { 34} }, // expression 466 | { { 274}, { 35} }, // IDENTIFIER 467 | { { 0}, { 0} }, 468 | }; 469 | 470 | SR__ s_32[] = 471 | { 472 | { { DEF_RED}, { 1} }, 473 | { { 0}, { -27} }, 474 | }; 475 | 476 | SR__ s_33[] = 477 | { 478 | { { REQ_DEF}, { 2} }, 479 | { { 278}, { 49} }, // COMMA 480 | { { 0}, { -28} }, 481 | }; 482 | 483 | SR__ s_34[] = 484 | { 485 | { { REQ_DEF}, { 2} }, 486 | { { 262}, { 50} }, // AS 487 | { { 0}, { -30} }, 488 | }; 489 | 490 | SR__ s_35[] = 491 | { 492 | { { DEF_RED}, { 1} }, 493 | { { 0}, { -78} }, 494 | }; 495 | 496 | SR__ s_36[] = 497 | { 498 | { { DEF_RED}, { 1} }, 499 | { { 0}, { -19} }, 500 | }; 501 | 502 | SR__ s_37[] = 503 | { 504 | { { DEF_RED}, { 1} }, 505 | { { 0}, { -17} }, 506 | }; 507 | 508 | SR__ s_38[] = 509 | { 510 | { { DEF_RED}, { 1} }, 511 | { { 0}, { -22} }, 512 | }; 513 | 514 | SR__ s_39[] = 515 | { 516 | { { DEF_RED}, { 1} }, 517 | { { 0}, { -24} }, 518 | }; 519 | 520 | SR__ s_40[] = 521 | { 522 | { { REQ_DEF}, { 3} }, 523 | { { 329}, { 51} }, // opt_variable_eq 524 | { { 274}, { 27} }, // IDENTIFIER 525 | { { 0}, { -40} }, 526 | }; 527 | 528 | SR__ s_41[] = 529 | { 530 | { { DEF_RED}, { 1} }, 531 | { { 0}, { -47} }, 532 | }; 533 | 534 | SR__ s_42[] = 535 | { 536 | { { REQ_DEF}, { 6} }, 537 | { { 287}, { 52} }, // EDGE 538 | { { 289}, { 53} }, // RIGHT_EDGE 539 | { { 288}, { 54} }, // LEFT_EDGE 540 | { { 290}, { 55} }, // SHAFT 541 | { { 291}, { 56} }, // LEFT_ARROW 542 | { { 0}, { -49} }, 543 | }; 544 | 545 | SR__ s_43[] = 546 | { 547 | { { REQ_DEF}, { 6} }, 548 | { { 335}, { 57} }, // opt_node_detail 549 | { { 336}, { 58} }, // node_detail 550 | { { 326}, { 59} }, // opt_node_name 551 | { { 325}, { 60} }, // node_name 552 | { { 274}, { 61} }, // IDENTIFIER 553 | { { 280}, { -35} }, // RIGHT_PAREN 554 | { { 283}, { -35} }, // LEFT_CURLY_BRACKET 555 | { { 297}, { -35} }, // COLON 556 | { { 0}, { -57} }, 557 | }; 558 | 559 | SR__ s_44[] = 560 | { 561 | { { DEF_RED}, { 1} }, 562 | { { 0}, { -41} }, 563 | }; 564 | 565 | SR__ s_45[] = 566 | { 567 | { { DEF_RED}, { 1} }, 568 | { { 0}, { -44} }, 569 | }; 570 | 571 | SR__ s_46[] = 572 | { 573 | { { REQ_TOKEN}, { 3} }, 574 | { { 324}, { 62} }, // expression 575 | { { 274}, { 35} }, // IDENTIFIER 576 | { { 0}, { 0} }, 577 | }; 578 | 579 | SR__ s_47[] = 580 | { 581 | { { REQ_DEF}, { 4} }, 582 | { { 330}, { 63} }, // opt_where 583 | { { 278}, { 40} }, // COMMA 584 | { { 264}, { 46} }, // WHERE 585 | { { 0}, { -42} }, 586 | }; 587 | 588 | SR__ s_48[] = 589 | { 590 | { { DEF_RED}, { 1} }, 591 | { { 0}, { -26} }, 592 | }; 593 | 594 | SR__ s_49[] = 595 | { 596 | { { REQ_TOKEN}, { 3} }, 597 | { { 324}, { 64} }, // expression 598 | { { 274}, { 35} }, // IDENTIFIER 599 | { { 0}, { 0} }, 600 | }; 601 | 602 | SR__ s_50[] = 603 | { 604 | { { REQ_TOKEN}, { 3} }, 605 | { { 323}, { 65} }, // variable 606 | { { 274}, { 66} }, // IDENTIFIER 607 | { { 0}, { 0} }, 608 | }; 609 | 610 | SR__ s_51[] = 611 | { 612 | { { REQ_TOKEN}, { 4} }, 613 | { { 332}, { 67} }, // pattern_element 614 | { { 333}, { 42} }, // node_pattern 615 | { { 279}, { 43} }, // LEFT_PAREN 616 | { { 0}, { 0} }, 617 | }; 618 | 619 | SR__ s_52[] = 620 | { 621 | { { REQ_TOKEN}, { 4} }, 622 | { { 332}, { 68} }, // pattern_element 623 | { { 333}, { 42} }, // node_pattern 624 | { { 279}, { 43} }, // LEFT_PAREN 625 | { { 0}, { 0} }, 626 | }; 627 | 628 | SR__ s_53[] = 629 | { 630 | { { REQ_TOKEN}, { 4} }, 631 | { { 332}, { 69} }, // pattern_element 632 | { { 333}, { 42} }, // node_pattern 633 | { { 279}, { 43} }, // LEFT_PAREN 634 | { { 0}, { 0} }, 635 | }; 636 | 637 | SR__ s_54[] = 638 | { 639 | { { REQ_TOKEN}, { 4} }, 640 | { { 332}, { 70} }, // pattern_element 641 | { { 333}, { 42} }, // node_pattern 642 | { { 279}, { 43} }, // LEFT_PAREN 643 | { { 0}, { 0} }, 644 | }; 645 | 646 | SR__ s_55[] = 647 | { 648 | { { REQ_TOKEN}, { 4} }, 649 | { { 334}, { 71} }, // relationship_pattern 650 | { { 339}, { 72} }, // relationship_detail 651 | { { 281}, { 73} }, // LEFT_BRACKET 652 | { { 0}, { 0} }, 653 | }; 654 | 655 | SR__ s_56[] = 656 | { 657 | { { REQ_TOKEN}, { 4} }, 658 | { { 334}, { 74} }, // relationship_pattern 659 | { { 339}, { 72} }, // relationship_detail 660 | { { 281}, { 73} }, // LEFT_BRACKET 661 | { { 0}, { 0} }, 662 | }; 663 | 664 | SR__ s_57[] = 665 | { 666 | { { REQ_TOKEN}, { 2} }, 667 | { { 280}, { 75} }, // RIGHT_PAREN 668 | { { 0}, { 0} }, 669 | }; 670 | 671 | SR__ s_58[] = 672 | { 673 | { { DEF_RED}, { 1} }, 674 | { { 0}, { -58} }, 675 | }; 676 | 677 | SR__ s_59[] = 678 | { 679 | { { REQ_DEF}, { 6} }, 680 | { { 337}, { 76} }, // opt_map_literal 681 | { { 338}, { 77} }, // node_labels 682 | { { 343}, { 78} }, // map_literal 683 | { { 297}, { 79} }, // COLON 684 | { { 283}, { 80} }, // LEFT_CURLY_BRACKET 685 | { { 0}, { -71} }, 686 | }; 687 | 688 | SR__ s_60[] = 689 | { 690 | { { DEF_RED}, { 1} }, 691 | { { 0}, { -36} }, 692 | }; 693 | 694 | SR__ s_61[] = 695 | { 696 | { { DEF_RED}, { 1} }, 697 | { { 0}, { -34} }, 698 | }; 699 | 700 | SR__ s_62[] = 701 | { 702 | { { DEF_RED}, { 1} }, 703 | { { 0}, { -43} }, 704 | }; 705 | 706 | SR__ s_63[] = 707 | { 708 | { { DEF_RED}, { 1} }, 709 | { { 0}, { -45} }, 710 | }; 711 | 712 | SR__ s_64[] = 713 | { 714 | { { REQ_DEF}, { 2} }, 715 | { { 262}, { 81} }, // AS 716 | { { 0}, { -32} }, 717 | }; 718 | 719 | SR__ s_65[] = 720 | { 721 | { { DEF_RED}, { 1} }, 722 | { { 0}, { -31} }, 723 | }; 724 | 725 | SR__ s_66[] = 726 | { 727 | { { DEF_RED}, { 1} }, 728 | { { 0}, { -29} }, 729 | }; 730 | 731 | SR__ s_67[] = 732 | { 733 | { { DEF_RED}, { 1} }, 734 | { { 0}, { -48} }, 735 | }; 736 | 737 | SR__ s_68[] = 738 | { 739 | { { DEF_RED}, { 1} }, 740 | { { 0}, { -50} }, 741 | }; 742 | 743 | SR__ s_69[] = 744 | { 745 | { { DEF_RED}, { 1} }, 746 | { { 0}, { -51} }, 747 | }; 748 | 749 | SR__ s_70[] = 750 | { 751 | { { DEF_RED}, { 1} }, 752 | { { 0}, { -52} }, 753 | }; 754 | 755 | SR__ s_71[] = 756 | { 757 | { { REQ_TOKEN}, { 3} }, 758 | { { 290}, { 82} }, // SHAFT 759 | { { 292}, { 83} }, // RIGHT_ARROW 760 | { { 0}, { 0} }, 761 | }; 762 | 763 | SR__ s_72[] = 764 | { 765 | { { DEF_RED}, { 1} }, 766 | { { 0}, { -63} }, 767 | }; 768 | 769 | SR__ s_73[] = 770 | { 771 | { { REQ_DEF}, { 4} }, 772 | { { 328}, { 84} }, // opt_relationship_name 773 | { { 327}, { 85} }, // relationship_name 774 | { { 274}, { 86} }, // IDENTIFIER 775 | { { 0}, { -38} }, 776 | }; 777 | 778 | SR__ s_74[] = 779 | { 780 | { { REQ_TOKEN}, { 2} }, 781 | { { 290}, { 87} }, // SHAFT 782 | { { 0}, { 0} }, 783 | }; 784 | 785 | SR__ s_75[] = 786 | { 787 | { { DEF_RED}, { 1} }, 788 | { { 0}, { -56} }, 789 | }; 790 | 791 | SR__ s_76[] = 792 | { 793 | { { DEF_RED}, { 1} }, 794 | { { 0}, { -59} }, 795 | }; 796 | 797 | SR__ s_77[] = 798 | { 799 | { { REQ_DEF}, { 5} }, 800 | { { 337}, { 88} }, // opt_map_literal 801 | { { 297}, { 89} }, // COLON 802 | { { 343}, { 78} }, // map_literal 803 | { { 283}, { 80} }, // LEFT_CURLY_BRACKET 804 | { { 0}, { -71} }, 805 | }; 806 | 807 | SR__ s_78[] = 808 | { 809 | { { DEF_RED}, { 1} }, 810 | { { 0}, { -72} }, 811 | }; 812 | 813 | SR__ s_79[] = 814 | { 815 | { { REQ_TOKEN}, { 2} }, 816 | { { 274}, { 90} }, // IDENTIFIER 817 | { { 0}, { 0} }, 818 | }; 819 | 820 | SR__ s_80[] = 821 | { 822 | { { REQ_TOKEN}, { 5} }, 823 | { { 346}, { 91} }, // property_key_value_pairs 824 | { { 345}, { 92} }, // property_key_value_pair 825 | { { 344}, { 93} }, // property_key_name 826 | { { 274}, { 94} }, // IDENTIFIER 827 | { { 0}, { 0} }, 828 | }; 829 | 830 | SR__ s_81[] = 831 | { 832 | { { REQ_TOKEN}, { 3} }, 833 | { { 323}, { 95} }, // variable 834 | { { 274}, { 66} }, // IDENTIFIER 835 | { { 0}, { 0} }, 836 | }; 837 | 838 | SR__ s_82[] = 839 | { 840 | { { REQ_TOKEN}, { 4} }, 841 | { { 332}, { 96} }, // pattern_element 842 | { { 333}, { 42} }, // node_pattern 843 | { { 279}, { 43} }, // LEFT_PAREN 844 | { { 0}, { 0} }, 845 | }; 846 | 847 | SR__ s_83[] = 848 | { 849 | { { REQ_TOKEN}, { 4} }, 850 | { { 332}, { 97} }, // pattern_element 851 | { { 333}, { 42} }, // node_pattern 852 | { { 279}, { 43} }, // LEFT_PAREN 853 | { { 0}, { 0} }, 854 | }; 855 | 856 | SR__ s_84[] = 857 | { 858 | { { REQ_DEF}, { 6} }, 859 | { { 342}, { 98} }, // opt_relationship_label 860 | { { 341}, { 99} }, // relationship_label 861 | { { 340}, { 100} }, // relationship_label_pair 862 | { { 297}, { 101} }, // COLON 863 | { { 274}, { 102} }, // IDENTIFIER 864 | { { 0}, { -68} }, 865 | }; 866 | 867 | SR__ s_85[] = 868 | { 869 | { { DEF_RED}, { 1} }, 870 | { { 0}, { -39} }, 871 | }; 872 | 873 | SR__ s_86[] = 874 | { 875 | { { DEF_RED}, { 1} }, 876 | { { 0}, { -37} }, 877 | }; 878 | 879 | SR__ s_87[] = 880 | { 881 | { { REQ_TOKEN}, { 4} }, 882 | { { 332}, { 103} }, // pattern_element 883 | { { 333}, { 42} }, // node_pattern 884 | { { 279}, { 43} }, // LEFT_PAREN 885 | { { 0}, { 0} }, 886 | }; 887 | 888 | SR__ s_88[] = 889 | { 890 | { { DEF_RED}, { 1} }, 891 | { { 0}, { -60} }, 892 | }; 893 | 894 | SR__ s_89[] = 895 | { 896 | { { REQ_TOKEN}, { 2} }, 897 | { { 274}, { 104} }, // IDENTIFIER 898 | { { 0}, { 0} }, 899 | }; 900 | 901 | SR__ s_90[] = 902 | { 903 | { { DEF_RED}, { 1} }, 904 | { { 0}, { -61} }, 905 | }; 906 | 907 | SR__ s_91[] = 908 | { 909 | { { REQ_TOKEN}, { 3} }, 910 | { { 284}, { 105} }, // RIGHT_CURLY_BRACKET 911 | { { 278}, { 106} }, // COMMA 912 | { { 0}, { 0} }, 913 | }; 914 | 915 | SR__ s_92[] = 916 | { 917 | { { DEF_RED}, { 1} }, 918 | { { 0}, { -75} }, 919 | }; 920 | 921 | SR__ s_93[] = 922 | { 923 | { { REQ_TOKEN}, { 2} }, 924 | { { 297}, { 107} }, // COLON 925 | { { 0}, { 0} }, 926 | }; 927 | 928 | SR__ s_94[] = 929 | { 930 | { { DEF_RED}, { 1} }, 931 | { { 0}, { -73} }, 932 | }; 933 | 934 | SR__ s_95[] = 935 | { 936 | { { DEF_RED}, { 1} }, 937 | { { 0}, { -33} }, 938 | }; 939 | 940 | SR__ s_96[] = 941 | { 942 | { { DEF_RED}, { 1} }, 943 | { { 0}, { -53} }, 944 | }; 945 | 946 | SR__ s_97[] = 947 | { 948 | { { DEF_RED}, { 1} }, 949 | { { 0}, { -54} }, 950 | }; 951 | 952 | SR__ s_98[] = 953 | { 954 | { { REQ_TOKEN}, { 2} }, 955 | { { 282}, { 108} }, // RIGHT_BRACKET 956 | { { 0}, { 0} }, 957 | }; 958 | 959 | SR__ s_99[] = 960 | { 961 | { { REQ_DEF}, { 2} }, 962 | { { 303}, { 109} }, // BAR 963 | { { 0}, { -69} }, 964 | }; 965 | 966 | SR__ s_100[] = 967 | { 968 | { { DEF_RED}, { 1} }, 969 | { { 0}, { -66} }, 970 | }; 971 | 972 | SR__ s_101[] = 973 | { 974 | { { REQ_TOKEN}, { 2} }, 975 | { { 274}, { 110} }, // IDENTIFIER 976 | { { 0}, { 0} }, 977 | }; 978 | 979 | SR__ s_102[] = 980 | { 981 | { { DEF_RED}, { 1} }, 982 | { { 0}, { -65} }, 983 | }; 984 | 985 | SR__ s_103[] = 986 | { 987 | { { DEF_RED}, { 1} }, 988 | { { 0}, { -55} }, 989 | }; 990 | 991 | SR__ s_104[] = 992 | { 993 | { { DEF_RED}, { 1} }, 994 | { { 0}, { -62} }, 995 | }; 996 | 997 | SR__ s_105[] = 998 | { 999 | { { DEF_RED}, { 1} }, 1000 | { { 0}, { -77} }, 1001 | }; 1002 | 1003 | SR__ s_106[] = 1004 | { 1005 | { { REQ_TOKEN}, { 4} }, 1006 | { { 345}, { 111} }, // property_key_value_pair 1007 | { { 344}, { 93} }, // property_key_name 1008 | { { 274}, { 94} }, // IDENTIFIER 1009 | { { 0}, { 0} }, 1010 | }; 1011 | 1012 | SR__ s_107[] = 1013 | { 1014 | { { REQ_TOKEN}, { 3} }, 1015 | { { 324}, { 112} }, // expression 1016 | { { 274}, { 35} }, // IDENTIFIER 1017 | { { 0}, { 0} }, 1018 | }; 1019 | 1020 | SR__ s_108[] = 1021 | { 1022 | { { DEF_RED}, { 1} }, 1023 | { { 0}, { -70} }, 1024 | }; 1025 | 1026 | SR__ s_109[] = 1027 | { 1028 | { { REQ_TOKEN}, { 4} }, 1029 | { { 340}, { 113} }, // relationship_label_pair 1030 | { { 297}, { 101} }, // COLON 1031 | { { 274}, { 102} }, // IDENTIFIER 1032 | { { 0}, { 0} }, 1033 | }; 1034 | 1035 | SR__ s_110[] = 1036 | { 1037 | { { DEF_RED}, { 1} }, 1038 | { { 0}, { -64} }, 1039 | }; 1040 | 1041 | SR__ s_111[] = 1042 | { 1043 | { { DEF_RED}, { 1} }, 1044 | { { 0}, { -76} }, 1045 | }; 1046 | 1047 | SR__ s_112[] = 1048 | { 1049 | { { DEF_RED}, { 1} }, 1050 | { { 0}, { -74} }, 1051 | }; 1052 | 1053 | SR__ s_113[] = 1054 | { 1055 | { { DEF_RED}, { 1} }, 1056 | { { 0}, { -67} }, 1057 | }; 1058 | 1059 | 1060 | // State array: 1061 | SR__ *s_state[] = 1062 | { 1063 | s_0, s_1, s_2, s_3, s_4, s_5, s_6, s_7, s_8, s_9, 1064 | s_10, s_11, s_12, s_13, s_14, s_15, s_16, s_17, s_18, s_19, 1065 | s_20, s_21, s_22, s_23, s_24, s_25, s_26, s_27, s_28, s_29, 1066 | s_30, s_31, s_32, s_33, s_34, s_35, s_36, s_37, s_38, s_39, 1067 | s_40, s_41, s_42, s_43, s_44, s_45, s_46, s_47, s_48, s_49, 1068 | s_50, s_51, s_52, s_53, s_54, s_55, s_56, s_57, s_58, s_59, 1069 | s_60, s_61, s_62, s_63, s_64, s_65, s_66, s_67, s_68, s_69, 1070 | s_70, s_71, s_72, s_73, s_74, s_75, s_76, s_77, s_78, s_79, 1071 | s_80, s_81, s_82, s_83, s_84, s_85, s_86, s_87, s_88, s_89, 1072 | s_90, s_91, s_92, s_93, s_94, s_95, s_96, s_97, s_98, s_99, 1073 | s_100, s_101, s_102, s_103, s_104, s_105, s_106, s_107, s_108, s_109, 1074 | s_110, s_111, s_112, s_113, 1075 | }; 1076 | 1077 | typedef std::unordered_map SMap; 1078 | typedef SMap::value_type SMapVal; 1079 | 1080 | SMapVal s_symArr[] = 1081 | { 1082 | SMapVal(-2, "_UNDETERMINED_"), // predefined symbols 1083 | SMapVal(-1, "_EOF_"), 1084 | SMapVal(256, "_error_"), 1085 | 1086 | SMapVal(257, "ALL"), 1087 | SMapVal(258, "UNION"), 1088 | SMapVal(259, "MATCH"), 1089 | SMapVal(260, "CREATE"), 1090 | SMapVal(261, "RETURN"), 1091 | SMapVal(262, "AS"), 1092 | SMapVal(263, "DISTINCT"), 1093 | SMapVal(264, "WHERE"), 1094 | SMapVal(265, "ORDER"), 1095 | SMapVal(266, "BY"), 1096 | SMapVal(267, "ASC"), 1097 | SMapVal(268, "DESC"), 1098 | SMapVal(269, "LIMIT"), 1099 | SMapVal(270, "AND"), 1100 | SMapVal(271, "OR"), 1101 | SMapVal(272, "TRUE"), 1102 | SMapVal(273, "FALSE"), 1103 | SMapVal(274, "IDENTIFIER"), 1104 | SMapVal(275, "FLOAT"), 1105 | SMapVal(276, "INTEGER"), 1106 | SMapVal(277, "STRING"), 1107 | SMapVal(278, "COMMA"), 1108 | SMapVal(279, "LEFT_PAREN"), 1109 | SMapVal(280, "RIGHT_PAREN"), 1110 | SMapVal(281, "LEFT_BRACKET"), 1111 | SMapVal(282, "RIGHT_BRACKET"), 1112 | SMapVal(283, "LEFT_CURLY_BRACKET"), 1113 | SMapVal(284, "RIGHT_CURLY_BRACKET"), 1114 | SMapVal(285, "GE"), 1115 | SMapVal(286, "LE"), 1116 | SMapVal(287, "EDGE"), 1117 | SMapVal(288, "LEFT_EDGE"), 1118 | SMapVal(289, "RIGHT_EDGE"), 1119 | SMapVal(290, "SHAFT"), 1120 | SMapVal(291, "LEFT_ARROW"), 1121 | SMapVal(292, "RIGHT_ARROW"), 1122 | SMapVal(293, "GT"), 1123 | SMapVal(294, "LT"), 1124 | SMapVal(295, "NE"), 1125 | SMapVal(296, "EQ"), 1126 | SMapVal(297, "COLON"), 1127 | SMapVal(298, "SEMICOLON"), 1128 | SMapVal(299, "DOT"), 1129 | SMapVal(300, "ASTERISK"), 1130 | SMapVal(301, "OPTIONAL"), 1131 | SMapVal(302, "DOLLAR"), 1132 | SMapVal(303, "BAR"), 1133 | SMapVal(304, "start_rule"), 1134 | SMapVal(305, "cypher"), 1135 | SMapVal(306, "statement"), 1136 | SMapVal(307, "query"), 1137 | SMapVal(308, "regular_query"), 1138 | SMapVal(309, "single_query"), 1139 | SMapVal(310, "single_part_query"), 1140 | SMapVal(311, "read_only_end"), 1141 | SMapVal(312, "read_update_end"), 1142 | SMapVal(313, "updating_end"), 1143 | SMapVal(314, "read_part"), 1144 | SMapVal(315, "return"), 1145 | SMapVal(316, "reading_clause"), 1146 | SMapVal(317, "match"), 1147 | SMapVal(318, "updating_clause"), 1148 | SMapVal(319, "create"), 1149 | SMapVal(320, "opt_return"), 1150 | SMapVal(321, "return_body"), 1151 | SMapVal(322, "expression_list"), 1152 | SMapVal(323, "variable"), 1153 | SMapVal(324, "expression"), 1154 | SMapVal(325, "node_name"), 1155 | SMapVal(326, "opt_node_name"), 1156 | SMapVal(327, "relationship_name"), 1157 | SMapVal(328, "opt_relationship_name"), 1158 | SMapVal(329, "opt_variable_eq"), 1159 | SMapVal(330, "opt_where"), 1160 | SMapVal(331, "pattern"), 1161 | SMapVal(332, "pattern_element"), 1162 | SMapVal(333, "node_pattern"), 1163 | SMapVal(334, "relationship_pattern"), 1164 | SMapVal(335, "opt_node_detail"), 1165 | SMapVal(336, "node_detail"), 1166 | SMapVal(337, "opt_map_literal"), 1167 | SMapVal(338, "node_labels"), 1168 | SMapVal(339, "relationship_detail"), 1169 | SMapVal(340, "relationship_label_pair"), 1170 | SMapVal(341, "relationship_label"), 1171 | SMapVal(342, "opt_relationship_label"), 1172 | SMapVal(343, "map_literal"), 1173 | SMapVal(344, "property_key_name"), 1174 | SMapVal(345, "property_key_value_pair"), 1175 | SMapVal(346, "property_key_value_pairs"), 1176 | SMapVal(347, "start_rule_$"), 1177 | }; 1178 | 1179 | SMap s_symbol 1180 | ( 1181 | s_symArr, s_symArr + sizeof(s_symArr) / sizeof(SMapVal) 1182 | ); 1183 | 1184 | } // anonymous namespace ends 1185 | 1186 | 1187 | 1188 | // If the parsing function call uses arguments, then provide an overloaded 1189 | // function. The code below doesn't rely on parameters, so no arguments are 1190 | // required. Furthermore, parse uses a function try block to allow us to do 1191 | // ACCEPT and ABORT from anywhere, even from within members called by actions, 1192 | // simply throwing the appropriate exceptions. 1193 | 1194 | ParserBase::ParserBase() 1195 | : 1196 | d_stackIdx__(-1), 1197 | // $insert debuginit 1198 | d_debug__(false), 1199 | d_nErrors__(0), 1200 | // $insert requiredtokens 1201 | d_requiredTokens__(0), 1202 | d_acceptedTokens__(d_requiredTokens__), 1203 | d_token__(_UNDETERMINED_), 1204 | d_nextToken__(_UNDETERMINED_) 1205 | {} 1206 | 1207 | // $insert debugfunctions 1208 | std::string ParserBase::symbol__(int value) const 1209 | { 1210 | using namespace std; 1211 | ostringstream ostr; 1212 | SMap::const_iterator it = s_symbol.find(value); 1213 | if (it != s_symbol.end()) 1214 | ostr << '\'' << it->second << '\''; 1215 | else if (isprint(value)) 1216 | ostr << '`' << static_cast(value) << "' (" << value << ')'; 1217 | else 1218 | ostr << "'\\x" << setfill('0') << hex << setw(2) << value << '\''; 1219 | return ostr.str(); 1220 | } 1221 | 1222 | 1223 | 1224 | void Parser::print__() 1225 | { 1226 | // $insert print 1227 | 1228 | enum { _UNDETERMINED_ = -2 }; 1229 | 1230 | std::cout << "Token: " << symbol__(d_token__) << ", text: `"; 1231 | if (d_token__ == _UNDETERMINED_) 1232 | std::cout << "'\n"; 1233 | else 1234 | std::cout << d_scanner.matched() << "'\n"; 1235 | } 1236 | 1237 | void ParserBase::clearin() 1238 | { 1239 | d_token__ = d_nextToken__ = _UNDETERMINED_; 1240 | } 1241 | 1242 | void ParserBase::push__(size_t state) 1243 | { 1244 | if (static_cast(d_stackIdx__ + 1) == d_stateStack__.size()) 1245 | { 1246 | size_t newSize = d_stackIdx__ + STACK_EXPANSION; 1247 | d_stateStack__.resize(newSize); 1248 | d_valueStack__.resize(newSize); 1249 | } 1250 | ++d_stackIdx__; 1251 | d_stateStack__[d_stackIdx__] = d_state__ = state; 1252 | *(d_vsp__ = &d_valueStack__[d_stackIdx__]) = d_val__; 1253 | } 1254 | 1255 | void ParserBase::popToken__() 1256 | { 1257 | d_token__ = d_nextToken__; 1258 | 1259 | d_val__ = d_nextVal__; 1260 | d_nextVal__ = STYPE__(); 1261 | 1262 | d_nextToken__ = _UNDETERMINED_; 1263 | } 1264 | 1265 | void ParserBase::pushToken__(int token) 1266 | { 1267 | d_nextToken__ = d_token__; 1268 | d_nextVal__ = d_val__; 1269 | d_token__ = token; 1270 | } 1271 | 1272 | void ParserBase::pop__(size_t count) 1273 | { 1274 | if (d_stackIdx__ < static_cast(count)) 1275 | { 1276 | ABORT(); 1277 | } 1278 | 1279 | d_stackIdx__ -= count; 1280 | d_state__ = d_stateStack__[d_stackIdx__]; 1281 | d_vsp__ = &d_valueStack__[d_stackIdx__]; 1282 | } 1283 | 1284 | inline size_t ParserBase::top__() const 1285 | { 1286 | return d_stateStack__[d_stackIdx__]; 1287 | } 1288 | 1289 | void Parser::executeAction(int production) 1290 | try 1291 | { 1292 | if (d_token__ != _UNDETERMINED_) 1293 | pushToken__(d_token__); // save an already available token 1294 | 1295 | // $insert defaultactionreturn 1296 | // save default non-nested block $$ 1297 | if (int size = s_productionInfo[production].d_size) 1298 | d_val__ = d_vsp__[1 - size]; 1299 | 1300 | switch (production) 1301 | { 1302 | // $insert actioncases 1303 | 1304 | case 2: 1305 | #line 93 "grammar.y" 1306 | { std::cout << " cypher: statement "; } 1307 | break; 1308 | 1309 | case 5: 1310 | #line 102 "grammar.y" 1311 | { std::cout << " query: regular_query"; } 1312 | break; 1313 | 1314 | } 1315 | } 1316 | catch (std::exception const &exc) 1317 | { 1318 | exceptionHandler__(exc); 1319 | } 1320 | 1321 | inline void ParserBase::reduce__(PI__ const &pi) 1322 | { 1323 | d_token__ = pi.d_nonTerm; 1324 | pop__(pi.d_size); 1325 | 1326 | } 1327 | 1328 | // If d_token__ is _UNDETERMINED_ then if d_nextToken__ is _UNDETERMINED_ another 1329 | // token is obtained from lex(). Then d_nextToken__ is assigned to d_token__. 1330 | void Parser::nextToken() 1331 | { 1332 | if (d_token__ != _UNDETERMINED_) // no need for a token: got one 1333 | return; // already 1334 | 1335 | if (d_nextToken__ != _UNDETERMINED_) 1336 | { 1337 | popToken__(); // consume pending token 1338 | } 1339 | else 1340 | { 1341 | ++d_acceptedTokens__; // accept another token (see 1342 | // errorRecover()) 1343 | d_token__ = lex(); 1344 | if (d_token__ <= 0) 1345 | d_token__ = _EOF_; 1346 | } 1347 | print(); 1348 | } 1349 | 1350 | // if the final transition is negative, then we should reduce by the rule 1351 | // given by its positive value. Note that the `recovery' parameter is only 1352 | // used with the --debug option 1353 | int Parser::lookup(bool recovery) 1354 | { 1355 | // $insert threading 1356 | SR__ *sr = s_state[d_state__]; // get the appropriate state-table 1357 | int lastIdx = sr->d_lastIdx; // sentinel-index in the SR__ array 1358 | 1359 | SR__ *lastElementPtr = sr + lastIdx; 1360 | lastElementPtr->d_token = d_token__; // set search-token 1361 | 1362 | SR__ *elementPtr = sr + 1; // start the search at s_xx[1] 1363 | while (elementPtr->d_token != d_token__) 1364 | ++elementPtr; 1365 | 1366 | 1367 | if (elementPtr == lastElementPtr) // reached the last element 1368 | { 1369 | if (elementPtr->d_action < 0) // default reduction 1370 | { 1371 | return elementPtr->d_action; 1372 | } 1373 | 1374 | // No default reduction, so token not found, so error. 1375 | throw UNEXPECTED_TOKEN__; 1376 | } 1377 | 1378 | // not at the last element: inspect the nature of the action 1379 | // (< 0: reduce, 0: ACCEPT, > 0: shift) 1380 | 1381 | int action = elementPtr->d_action; 1382 | 1383 | 1384 | return action; 1385 | } 1386 | 1387 | // When an error has occurred, pop elements off the stack until the top 1388 | // state has an error-item. If none is found, the default recovery 1389 | // mode (which is to abort) is activated. 1390 | // 1391 | // If EOF is encountered without being appropriate for the current state, 1392 | // then the error recovery will fall back to the default recovery mode. 1393 | // (i.e., parsing terminates) 1394 | void Parser::errorRecovery() 1395 | try 1396 | { 1397 | if (d_acceptedTokens__ >= d_requiredTokens__)// only generate an error- 1398 | { // message if enough tokens 1399 | ++d_nErrors__; // were accepted. Otherwise 1400 | error("Syntax error"); // simply skip input 1401 | 1402 | } 1403 | 1404 | 1405 | // get the error state 1406 | while (not (s_state[top__()][0].d_type & ERR_ITEM)) 1407 | { 1408 | pop__(); 1409 | } 1410 | 1411 | // In the error state, lookup a token allowing us to proceed. 1412 | // Continuation may be possible following multiple reductions, 1413 | // but eventuall a shift will be used, requiring the retrieval of 1414 | // a terminal token. If a retrieved token doesn't match, the catch below 1415 | // will ensure the next token is requested in the while(true) block 1416 | // implemented below: 1417 | 1418 | int lastToken = d_token__; // give the unexpected token a 1419 | // chance to be processed 1420 | // again. 1421 | 1422 | pushToken__(_error_); // specify _error_ as next token 1423 | push__(lookup(true)); // push the error state 1424 | 1425 | d_token__ = lastToken; // reactivate the unexpected 1426 | // token (we're now in an 1427 | // ERROR state). 1428 | 1429 | bool gotToken = true; // the next token is a terminal 1430 | 1431 | while (true) 1432 | { 1433 | try 1434 | { 1435 | if (s_state[d_state__]->d_type & REQ_TOKEN) 1436 | { 1437 | gotToken = d_token__ == _UNDETERMINED_; 1438 | nextToken(); // obtain next token 1439 | } 1440 | 1441 | int action = lookup(true); 1442 | 1443 | if (action > 0) // push a new state 1444 | { 1445 | push__(action); 1446 | popToken__(); 1447 | 1448 | if (gotToken) 1449 | { 1450 | 1451 | d_acceptedTokens__ = 0; 1452 | return; 1453 | } 1454 | } 1455 | else if (action < 0) 1456 | { 1457 | // no actions executed on recovery but save an already 1458 | // available token: 1459 | if (d_token__ != _UNDETERMINED_) 1460 | pushToken__(d_token__); 1461 | 1462 | // next token is the rule's LHS 1463 | reduce__(s_productionInfo[-action]); 1464 | } 1465 | else 1466 | ABORT(); // abort when accepting during 1467 | // error recovery 1468 | } 1469 | catch (...) 1470 | { 1471 | if (d_token__ == _EOF_) 1472 | ABORT(); // saw inappropriate _EOF_ 1473 | 1474 | popToken__(); // failing token now skipped 1475 | } 1476 | } 1477 | } 1478 | catch (ErrorRecovery__) // This is: DEFAULT_RECOVERY_MODE 1479 | { 1480 | ABORT(); 1481 | } 1482 | 1483 | // The parsing algorithm: 1484 | // Initially, state 0 is pushed on the stack, and d_token__ as well as 1485 | // d_nextToken__ are initialized to _UNDETERMINED_. 1486 | // 1487 | // Then, in an eternal loop: 1488 | // 1489 | // 1. If a state does not have REQ_TOKEN no token is assigned to 1490 | // d_token__. If the state has REQ_TOKEN, nextToken() is called to 1491 | // determine d_nextToken__ and d_token__ is set to 1492 | // d_nextToken__. nextToken() will not call lex() unless d_nextToken__ is 1493 | // _UNDETERMINED_. 1494 | // 1495 | // 2. lookup() is called: 1496 | // d_token__ is stored in the final element's d_token field of the 1497 | // state's SR_ array. 1498 | // 1499 | // 3. The current token is looked up in the state's SR_ array 1500 | // 1501 | // 4. Depending on the result of the lookup() function the next state is 1502 | // shifted on the parser's stack, a reduction by some rule is applied, 1503 | // or the parsing function returns ACCEPT(). When a reduction is 1504 | // called for, any action that may have been defined for that 1505 | // reduction is executed. 1506 | // 1507 | // 5. An error occurs if d_token__ is not found, and the state has no 1508 | // default reduction. Error handling was described at the top of this 1509 | // file. 1510 | 1511 | int Parser::parse() 1512 | try 1513 | { 1514 | push__(0); // initial state 1515 | clearin(); // clear the tokens. 1516 | 1517 | while (true) 1518 | { 1519 | try 1520 | { 1521 | if (s_state[d_state__]->d_type & REQ_TOKEN) 1522 | nextToken(); // obtain next token 1523 | 1524 | 1525 | int action = lookup(false); // lookup d_token__ in d_state__ 1526 | 1527 | if (action > 0) // SHIFT: push a new state 1528 | { 1529 | push__(action); 1530 | popToken__(); // token processed 1531 | } 1532 | else if (action < 0) // REDUCE: execute and pop. 1533 | { 1534 | executeAction(-action); 1535 | // next token is the rule's LHS 1536 | reduce__(s_productionInfo[-action]); 1537 | } 1538 | else 1539 | ACCEPT(); 1540 | } 1541 | catch (ErrorRecovery__) 1542 | { 1543 | errorRecovery(); 1544 | } 1545 | } 1546 | } 1547 | catch (Return__ retValue) 1548 | { 1549 | return retValue; 1550 | } 1551 | 1552 | 1553 | 1554 | -------------------------------------------------------------------------------- /src/scanner/Scanner.h: -------------------------------------------------------------------------------- 1 | // Generated by Flexc++ V2.03.04 on Thu, 17 Aug 2017 22:38:02 -0400 2 | 3 | #ifndef Scanner_H_INCLUDED_ 4 | #define Scanner_H_INCLUDED_ 5 | 6 | // $insert baseclass_h 7 | #include "Scannerbase.h" 8 | 9 | 10 | // $insert classHead 11 | class Scanner: public ScannerBase 12 | { 13 | public: 14 | explicit Scanner(std::istream &in = std::cin, 15 | std::ostream &out = std::cout); 16 | 17 | Scanner(std::string const &infile, std::string const &outfile); 18 | 19 | // $insert lexFunctionDecl 20 | int lex(); 21 | 22 | private: 23 | int lex__(); 24 | int executeAction__(size_t ruleNr); 25 | 26 | void print(); 27 | void preCode(); // re-implement this function for code that must 28 | // be exec'ed before the patternmatching starts 29 | 30 | void postCode(PostEnum__ type); 31 | // re-implement this function for code that must 32 | // be exec'ed after the rules's actions. 33 | }; 34 | 35 | // $insert scannerConstructors 36 | inline Scanner::Scanner(std::istream &in, std::ostream &out) 37 | : 38 | ScannerBase(in, out) 39 | {} 40 | 41 | inline Scanner::Scanner(std::string const &infile, std::string const &outfile) 42 | : 43 | ScannerBase(infile, outfile) 44 | {} 45 | 46 | // $insert inlineLexFunction 47 | inline int Scanner::lex() 48 | { 49 | return lex__(); 50 | } 51 | 52 | inline void Scanner::preCode() 53 | { 54 | // optionally replace by your own code 55 | } 56 | 57 | inline void Scanner::postCode(PostEnum__ type) 58 | { 59 | // optionally replace by your own code 60 | } 61 | 62 | inline void Scanner::print() 63 | { 64 | print__(); 65 | } 66 | 67 | 68 | #endif // Scanner_H_INCLUDED_ 69 | 70 | -------------------------------------------------------------------------------- /src/scanner/Scanner.ih: -------------------------------------------------------------------------------- 1 | /* 2 | BSD 3-Clause License 3 | 4 | Copyright (c) 2017, expertcompsci 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | * Neither the name of the copyright holder nor the names of its 18 | contributors may be used to endorse or promote products derived from 19 | this software without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 25 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | 33 | // $insert class_h 34 | #include "Scanner.h" 35 | #include "../parser/Parserbase.h" 36 | -------------------------------------------------------------------------------- /src/scanner/Scannerbase.h: -------------------------------------------------------------------------------- 1 | // Generated by Flexc++ V2.03.04 on Sat, 26 Aug 2017 21:58:52 -0400 2 | 3 | #ifndef ScannerBASE_H_INCLUDED 4 | #define ScannerBASE_H_INCLUDED 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | 14 | 15 | class ScannerBase 16 | { 17 | // idx: rule, value: tail length (NO_INCREMENTS if no tail) 18 | typedef std::vector VectorInt; 19 | 20 | static size_t const s_unavailable = std::numeric_limits::max(); 21 | 22 | enum 23 | { 24 | AT_EOF = -1 25 | }; 26 | 27 | protected: 28 | enum Leave__ 29 | {}; 30 | 31 | enum class ActionType__ 32 | { 33 | CONTINUE, // transition succeeded, go on 34 | ECHO_CH, // echo ch itself (d_matched empty) 35 | ECHO_FIRST, // echo d_matched[0], push back the rest 36 | MATCH, // matched a rule 37 | RETURN, // no further continuation, lex returns 0. 38 | }; 39 | 40 | enum class PostEnum__ 41 | { 42 | END, // postCode called when lex__() ends 43 | POP, // postCode called after switching files 44 | RETURN, // postCode called when lex__() returns 45 | WIP // postCode called when a non-returning rule 46 | // was matched 47 | }; 48 | 49 | public: 50 | enum class StartCondition__ { 51 | // $insert startCondNames 52 | INITIAL, 53 | }; 54 | 55 | private: 56 | struct FinalData 57 | { 58 | size_t rule; 59 | size_t length; 60 | }; 61 | struct Final 62 | { 63 | FinalData std; 64 | FinalData bol; 65 | }; 66 | 67 | // class Input encapsulates all input operations. 68 | // Its member get() returns the next input character 69 | // $insert inputInterface 70 | 71 | class Input 72 | { 73 | std::deque d_deque; // pending input chars 74 | std::istream *d_in; // ptr for easy streamswitching 75 | size_t d_lineNr; // line count 76 | 77 | public: 78 | Input(); 79 | // iStream: dynamically allocated 80 | Input(std::istream *iStream, size_t lineNr = 1); 81 | size_t get(); // the next range 82 | void reRead(size_t ch); // push back 'ch' (if < 0x100) 83 | // push back str from idx 'fmIdx' 84 | void reRead(std::string const &str, size_t fmIdx); 85 | size_t lineNr() const 86 | { 87 | return d_lineNr; 88 | } 89 | size_t nPending() const 90 | { 91 | return d_deque.size(); 92 | } 93 | void setPending(size_t size) 94 | { 95 | d_deque.erase(d_deque.begin(), d_deque.end() - size); 96 | } 97 | void close() // force closing the stream 98 | { 99 | delete d_in; 100 | d_in = 0; // switchStreams also closes 101 | } 102 | 103 | private: 104 | size_t next(); // obtain the next character 105 | }; 106 | 107 | protected: 108 | struct StreamStruct 109 | { 110 | std::string pushedName; 111 | Input pushedInput; 112 | }; 113 | 114 | private: 115 | std::vector d_streamStack; 116 | 117 | std::string d_filename; // name of the currently processed 118 | static size_t s_istreamNr; // file. With istreams it receives 119 | // the name "", where 120 | // # is the sequence number of the 121 | // istream (starting at 1) 122 | int d_startCondition = 0; 123 | int d_lopSC = 0; 124 | 125 | size_t d_state = 0; 126 | int d_nextState; 127 | std::shared_ptr d_out; 128 | bool d_atBOL = true; // the matched text starts at BOL 129 | Final d_final; 130 | 131 | // only used interactively: 132 | std::istream *d_in; // points to the input stream 133 | std::shared_ptr d_line; // holds line fm d_in 134 | 135 | Input d_input; 136 | std::string d_matched; // matched characters 137 | std::string d_lopMatched; // matched lop-rule characters 138 | std::string::iterator d_lopIter; 139 | std::string::iterator d_lopTail; 140 | std::string::iterator d_lopEnd; 141 | 142 | size_t d_lopPending; // # pending input chars at lop1__ 143 | bool d_return; // return after a rule's action 144 | bool d_more = false; // set to true by more() 145 | 146 | size_t (ScannerBase::*d_get)() = &ScannerBase::getInput; 147 | 148 | protected: 149 | std::istream *d_in__; 150 | int d_token__; // returned by lex__ 151 | 152 | 153 | 154 | int const (*d_dfaBase__)[66]; 155 | 156 | static int const s_dfa__[][66]; 157 | static int const (*s_dfaBase__[])[66]; 158 | enum: bool { s_interactive__ = false }; 159 | enum: size_t { 160 | s_rangeOfEOF__ = 63, 161 | s_finIdx__ = 64, 162 | s_nRules__ = 55, 163 | s_maxSizeofStreamStack__ = 10 164 | }; 165 | static size_t const s_ranges__[]; 166 | static size_t const s_rf__[][2]; 167 | 168 | public: 169 | ScannerBase(ScannerBase const &other) = delete; 170 | ScannerBase &operator=(ScannerBase const &rhs) = delete; 171 | 172 | bool debug() const; 173 | std::string const &filename() const; 174 | std::string const &matched() const; 175 | 176 | size_t length() const; 177 | size_t lineNr() const; 178 | 179 | void setDebug(bool onOff); 180 | 181 | void switchOstream(std::ostream &out); 182 | void switchOstream(std::string const &outfilename); 183 | 184 | 185 | void switchStreams(std::istream &in, 186 | std::ostream &out = std::cout); 187 | 188 | void switchIstream(std::string const &infilename); 189 | void switchStreams(std::string const &infilename, 190 | std::string const &outfilename); 191 | 192 | 193 | // $insert interactiveDecl 194 | 195 | protected: 196 | ScannerBase(std::istream &in, std::ostream &out); 197 | ScannerBase(std::string const &infilename, std::string const &outfilename); 198 | ~ScannerBase(); 199 | 200 | StartCondition__ startCondition() const; // current start condition 201 | bool popStream(); 202 | std::ostream &out(); 203 | void begin(StartCondition__ startCondition); 204 | void echo() const; 205 | void leave(int retValue) const; 206 | 207 | // `accept(n)' returns all but the first `n' characters of the current 208 | // token back to the input stream, where they will be rescanned when the 209 | // scanner looks for the next match. 210 | // So, it matches n of the characters in the input buffer, and so it accepts 211 | // n characters, rescanning the rest. 212 | void accept(size_t nChars = 0); // former: less 213 | void redo(size_t nChars = 0); // rescan the last nChar 214 | // characters, reducing 215 | // length() by nChars 216 | void more(); 217 | void push(size_t ch); // push char to Input 218 | void push(std::string const &txt); // same: chars 219 | 220 | 221 | std::vector const &streamStack() const; 222 | 223 | void pushStream(std::istream &curStream); 224 | void pushStream(std::string const &curName); 225 | 226 | 227 | void setFilename(std::string const &name); 228 | void setMatched(std::string const &text); 229 | 230 | static std::string istreamName__(); 231 | 232 | // members used by lex__(): they end in __ and should not be used 233 | // otherwise. 234 | 235 | ActionType__ actionType__(size_t range); // next action 236 | bool return__(); // 'return' from codeblock 237 | size_t matched__(size_t ch); // handles a matched rule 238 | size_t getRange__(int ch); // convert char to range 239 | size_t get__(); // next character 240 | size_t state__() const; // current state 241 | void continue__(int ch); // handles a transition 242 | void echoCh__(size_t ch); // echoes ch, sets d_atBOL 243 | void echoFirst__(size_t ch); // handles unknown input 244 | void updateFinals__(); // update a state's Final info 245 | void noReturn__(); // d_return to false 246 | void print__() const; // optionally print token 247 | void pushFront__(size_t ch); // return char to Input 248 | void reset__(); // prepare for new cycle 249 | // next input stream: 250 | void switchStream__(std::istream &in, size_t lineNr); 251 | void lopf__(size_t tail); // matched fixed size tail 252 | void lop1__(int lopSC); // matched ab for a/b 253 | void lop2__(); // matches the LOP's b tail 254 | void lop3__(); // catch-all while matching b 255 | void lop4__(); // matches the LOP's a head 256 | 257 | private: 258 | size_t getInput(); 259 | size_t getLOP(); 260 | void p_pushStream(std::string const &name, std::istream *streamPtr); 261 | void setMatchedSize(size_t length); 262 | bool knownFinalState(); 263 | 264 | template 265 | static ReturnType constexpr as(ArgType value); 266 | static bool constexpr available(size_t value); 267 | static StartCondition__ constexpr SC(int sc); 268 | static int constexpr SC(StartCondition__ sc); 269 | }; 270 | 271 | inline ScannerBase::~ScannerBase() 272 | { 273 | d_input.close(); 274 | } 275 | 276 | template 277 | inline ReturnType constexpr ScannerBase::as(ArgType value) 278 | { 279 | return static_cast(value); 280 | } 281 | 282 | inline bool ScannerBase::knownFinalState() 283 | { 284 | return (d_atBOL && available(d_final.bol.rule)) || 285 | available(d_final.std.rule); 286 | } 287 | 288 | inline bool constexpr ScannerBase::available(size_t value) 289 | { 290 | return value != std::numeric_limits::max(); 291 | } 292 | 293 | inline ScannerBase::StartCondition__ constexpr ScannerBase::SC(int sc) 294 | { 295 | return as(sc); 296 | } 297 | 298 | inline int constexpr ScannerBase::SC(StartCondition__ sc) 299 | { 300 | return as(sc); 301 | } 302 | 303 | inline std::ostream &ScannerBase::out() 304 | { 305 | return *d_out; 306 | } 307 | 308 | inline void ScannerBase::push(size_t ch) 309 | { 310 | d_input.reRead(ch); 311 | } 312 | 313 | inline void ScannerBase::push(std::string const &str) 314 | { 315 | d_input.reRead(str, 0); 316 | } 317 | 318 | inline void ScannerBase::setFilename(std::string const &name) 319 | { 320 | d_filename = name; 321 | } 322 | 323 | inline void ScannerBase::setMatched(std::string const &text) 324 | { 325 | d_matched = text; 326 | } 327 | 328 | inline std::string const &ScannerBase::matched() const 329 | { 330 | return d_matched; 331 | } 332 | 333 | inline ScannerBase::StartCondition__ ScannerBase::startCondition() const 334 | { 335 | return SC(d_startCondition); 336 | } 337 | 338 | inline std::string const &ScannerBase::filename() const 339 | { 340 | return d_filename; 341 | } 342 | 343 | inline void ScannerBase::echo() const 344 | { 345 | *d_out << d_matched; 346 | } 347 | 348 | inline size_t ScannerBase::length() const 349 | { 350 | return d_matched.size(); 351 | } 352 | 353 | inline void ScannerBase::leave(int retValue) const 354 | { 355 | throw as(retValue); 356 | } 357 | 358 | inline size_t ScannerBase::lineNr() const 359 | { 360 | return d_input.lineNr(); 361 | } 362 | 363 | inline void ScannerBase::more() 364 | { 365 | d_more = true; 366 | } 367 | 368 | inline void ScannerBase::begin(StartCondition__ startCondition) 369 | { 370 | // d_state is reset to 0 by reset__() 371 | d_dfaBase__ = s_dfaBase__[d_startCondition = SC(startCondition)]; 372 | } 373 | 374 | inline size_t ScannerBase::state__() const 375 | { 376 | return d_state; 377 | } 378 | 379 | inline size_t ScannerBase::get__() 380 | { 381 | return (this->*d_get)(); 382 | } 383 | 384 | inline size_t ScannerBase::getInput() 385 | { 386 | return d_input.get(); 387 | } 388 | 389 | inline bool ScannerBase::return__() 390 | { 391 | return d_return; 392 | } 393 | 394 | inline void ScannerBase::noReturn__() 395 | { 396 | d_return = false; 397 | } 398 | 399 | 400 | #endif // ScannerBASE_H_INCLUDED 401 | -------------------------------------------------------------------------------- /src/scanner/lex.cc: -------------------------------------------------------------------------------- 1 | // Generated by Flexc++ V2.03.04 on Sat, 26 Aug 2017 21:58:52 -0400 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | // $insert class_ih 9 | #include "Scanner.ih" 10 | 11 | 12 | // s_ranges__: use (unsigned) characters as index to obtain 13 | // that character's range-number. 14 | // The range for EOF is defined in a constant in the 15 | // class header file 16 | size_t const ScannerBase::s_ranges__[] = 17 | { 18 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 19 | 3, 3, 3, 3, 3, 3, 3, 4, 5, 6, 7, 8, 9, 9, 9,10,11,12,13,14,15,16,17,18,18, 20 | 18,18,18,18,18,18,18,18,19,20,21,22,23,24,24,25,26,27,28,29,30,31,32,33,34, 21 | 34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,56,56, 22 | 56,57,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,59,60, 23 | 61,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62, 24 | 62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62, 25 | 62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62, 26 | 62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62, 27 | 62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62, 28 | 62,62,62,62,62,62, 29 | }; 30 | 31 | // s_dfa__ contains the rows of *all* DFAs ordered by start state. The 32 | // enum class StartCondition__ is defined in the baseclass header 33 | // StartCondition__::INITIAL is always 0. Each entry defines the row to 34 | // transit to if the column's character range was sensed. Row numbers are 35 | // relative to the used DFA, and d_dfaBase__ is set to the first row of 36 | // the subset to use. The row's final two values are respectively the 37 | // rule that may be matched at this state, and the rule's FINAL flag. If 38 | // the final value equals FINAL (= 1) then, if there's no continuation, 39 | // the rule is matched. If the BOL flag (8) is also set (so FINAL + BOL (= 40 | // 9) is set) then the rule only matches when d_atBOL is also true. 41 | int const ScannerBase::s_dfa__[][66] = 42 | { 43 | // INITIAL 44 | {-1, 1, 1,-1, 1, 2, 3,-1, 4,-1, 5, 6, 7, 8, 9,10,11,-1,12,13, 45 | 14,15,16,17,-1,18,19,20,21,22,23,22,22,22,22,24,25,22,26,22, 46 | 22,27,22,28,29,22,30,22,22,22,31,-1,32,-1,22,-1,22,22,22,33, 47 | 34,35,-1,-1, -1, -1}, // 0 48 | {-1, 1, 1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 49 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 50 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 51 | -1,-1,-1,-1, 19, -1}, // 1 52 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 53 | -1,-1,36,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 54 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 55 | -1,-1,-1,-1, -1, -1}, // 2 56 | {-1, 3,-1, 3, 3, 3,37, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 57 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 58 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 59 | 3, 3, 3,-1, -1, -1}, // 3 60 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 61 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 62 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 63 | -1,-1,-1,-1, 46, -1}, // 4 64 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 65 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 66 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 67 | -1,-1,-1,-1, 24, -1}, // 5 68 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 69 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 70 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 71 | -1,-1,-1,-1, 25, -1}, // 6 72 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 73 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 74 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 75 | -1,-1,-1,-1, 45, -1}, // 7 76 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,38,-1,39,-1, 77 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 78 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 79 | -1,-1,-1,-1, -1, -1}, // 8 80 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 81 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 82 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 83 | -1,-1,-1,-1, 23, -1}, // 9 84 | {-1,40,40,-1,40,-1,-1,-1,-1,-1,41,-1,-1,-1,-1,42,38,-1,39,-1, 85 | -1,-1,-1,43,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 86 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,41,-1,-1,-1,-1,-1,-1,-1,-1,-1, 87 | -1,-1,-1,-1, -1, -1}, // 10 88 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,44,-1, 89 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 90 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 91 | -1,-1,-1,-1, 44, -1}, // 11 92 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,45,-1,12,-1, 93 | -1,-1,-1,-1,-1,-1,-1,-1,-1,46,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 94 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,46,-1,-1, 95 | -1,-1,-1,-1, 18, -1}, // 12 96 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 97 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 98 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 99 | -1,-1,-1,-1, 42, -1}, // 13 100 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 101 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 102 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 103 | -1,-1,-1,-1, 43, -1}, // 14 104 | {-1,47,47,-1,47,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,48,-1,-1,-1,-1, 105 | -1,-1,49,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 106 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 107 | -1,-1,-1,-1, 39, -1}, // 15 108 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 109 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 110 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 111 | -1,-1,-1,-1, 41, -1}, // 16 112 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 113 | -1,-1,50,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 114 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 115 | -1,-1,-1,-1, 38, -1}, // 17 116 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 117 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,51,22,52,22,22, 118 | 22,22,53,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 119 | -1,-1,-1,-1, 20, -1}, // 18 120 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 121 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 122 | 22,22,22,22,22,22,22,22,54,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 123 | -1,-1,-1,-1, 20, -1}, // 19 124 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 125 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 126 | 22,55,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 127 | -1,-1,-1,-1, 20, -1}, // 20 128 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 129 | -1,-1,-1,-1,-1,22,22,22,22,56,22,22,22,57,22,22,22,22,22,22, 130 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 131 | -1,-1,-1,-1, 20, -1}, // 21 132 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 133 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 134 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 135 | -1,-1,-1,-1, 20, -1}, // 22 136 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 137 | -1,-1,-1,-1,-1,58,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 138 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 139 | -1,-1,-1,-1, 20, -1}, // 23 140 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 141 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,59,22,22,22,22,22,22, 142 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 143 | -1,-1,-1,-1, 20, -1}, // 24 144 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 145 | -1,-1,-1,-1,-1,60,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 146 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 147 | -1,-1,-1,-1, 20, -1}, // 25 148 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 149 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,61, 150 | 22,62,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 151 | -1,-1,-1,-1, 20, -1}, // 26 152 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 153 | -1,-1,-1,-1,-1,22,22,22,22,63,22,22,22,22,22,22,22,22,22,22, 154 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 155 | -1,-1,-1,-1, 20, -1}, // 27 156 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 157 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 158 | 22,64,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 159 | -1,-1,-1,-1, 20, -1}, // 28 160 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 161 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,65,22,22, 162 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 163 | -1,-1,-1,-1, 20, -1}, // 29 164 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 165 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,66,22,22,22,22,22,22,22, 166 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 167 | -1,-1,-1,-1, 20, -1}, // 30 168 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 169 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 170 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 171 | -1,-1,-1,-1, 26, -1}, // 31 172 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 173 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 174 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 175 | -1,-1,-1,-1, 27, -1}, // 32 176 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 177 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 178 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 179 | -1,-1,-1,-1, 28, -1}, // 33 180 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 181 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 182 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 183 | -1,-1,-1,-1, 47, -1}, // 34 184 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 185 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 186 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 187 | -1,-1,-1,-1, 29, -1}, // 35 188 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 189 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 190 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 191 | -1,-1,-1,-1, 40, -1}, // 36 192 | {-1, 3,-1, 3, 3, 3,37, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 193 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 194 | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 195 | 3, 3, 3,-1, 22, -1}, // 37 196 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,44,-1, 197 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 198 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 199 | -1,-1,-1,-1, -1, -1}, // 38 200 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,45,-1,39,-1, 201 | -1,-1,-1,-1,-1,-1,-1,-1,-1,46,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 202 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,46,-1,-1, 203 | -1,-1,-1,-1, 21, -1}, // 39 204 | {-1,40,40,-1,40,-1,-1,-1,-1,-1,41,-1,-1,-1,-1,42,-1,-1,-1,-1, 205 | -1,-1,-1,43,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 206 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,41,-1,-1,-1,-1,-1,-1,-1,-1,-1, 207 | -1,-1,-1,-1, -1, -1}, // 40 208 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 209 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 210 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 211 | -1,-1,-1,-1, 35, -1}, // 41 212 | {-1,67,67,-1,67,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 213 | -1,-1,-1,68,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 214 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 215 | -1,-1,-1,-1, 32, -1}, // 42 216 | {-1,43,43,-1,43,-1,-1,-1,-1,-1,69,-1,-1,-1,-1,-1,-1,-1,-1,-1, 217 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 218 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 219 | -1,-1,-1,-1, -1, -1}, // 43 220 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,44,-1, 221 | -1,-1,-1,-1,-1,-1,-1,-1,-1,46,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 222 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,46,-1,-1, 223 | -1,-1,-1,-1, 21, -1}, // 44 224 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,70,-1, 225 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 226 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 227 | -1,-1,-1,-1, -1, -1}, // 45 228 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,71,-1,71,-1,-1,72,-1, 229 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 230 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 231 | -1,-1,-1,-1, -1, -1}, // 46 232 | {-1,47,47,-1,47,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,48,-1,-1,-1,-1, 233 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 234 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 235 | -1,-1,-1,-1, -1, -1}, // 47 236 | {-1,48,48,-1,48,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,73,-1,-1,-1,-1, 237 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 238 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,74,-1,-1,-1,-1,-1,-1,-1,-1,-1, 239 | -1,-1,-1,-1, -1, -1}, // 48 240 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 241 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 242 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 243 | -1,-1,-1,-1, 31, -1}, // 49 244 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 245 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 246 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 247 | -1,-1,-1,-1, 30, -1}, // 50 248 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 249 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,75,22,22,22,22, 250 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 251 | -1,-1,-1,-1, 20, -1}, // 51 252 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 253 | -1,-1,-1,-1,-1,22,22,22,76,22,22,22,22,22,22,22,22,22,22,22, 254 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 255 | -1,-1,-1,-1, 20, -1}, // 52 256 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 257 | -1,-1,-1,-1,-1,22,22,77,22,22,22,22,22,22,22,22,22,22,22,22, 258 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 259 | -1,-1,-1,-1, 5, -1}, // 53 260 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 261 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 262 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 263 | -1,-1,-1,-1, 9, -1}, // 54 264 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 265 | -1,-1,-1,-1,-1,22,22,22,22,78,22,22,22,22,22,22,22,22,22,22, 266 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 267 | -1,-1,-1,-1, 20, -1}, // 55 268 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 269 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 270 | 22,22,79,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 271 | -1,-1,-1,-1, 20, -1}, // 56 272 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 273 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 274 | 22,22,80,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 275 | -1,-1,-1,-1, 20, -1}, // 57 276 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 277 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,81,22,22,22,22, 278 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 279 | -1,-1,-1,-1, 20, -1}, // 58 280 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 281 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,82,22,22,22, 282 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 283 | -1,-1,-1,-1, 20, -1}, // 59 284 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 285 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 286 | 22,22,22,83,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 287 | -1,-1,-1,-1, 20, -1}, // 60 288 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 289 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 290 | 22,22,22,84,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 291 | -1,-1,-1,-1, 20, -1}, // 61 292 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 293 | -1,-1,-1,-1,-1,22,22,22,85,22,22,22,22,22,22,22,22,22,22,22, 294 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 295 | -1,-1,-1,-1, 14, -1}, // 62 296 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 297 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 298 | 22,22,22,86,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 299 | -1,-1,-1,-1, 20, -1}, // 63 300 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 301 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 302 | 22,22,22,22,87,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 303 | -1,-1,-1,-1, 20, -1}, // 64 304 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 305 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,88,22,22,22,22,22,22, 306 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 307 | -1,-1,-1,-1, 20, -1}, // 65 308 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 309 | -1,-1,-1,-1,-1,22,22,22,22,89,22,22,22,22,22,22,22,22,22,22, 310 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 311 | -1,-1,-1,-1, 20, -1}, // 66 312 | {-1,67,67,-1,67,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 313 | -1,-1,-1,68,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 314 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 315 | -1,-1,-1,-1, -1, -1}, // 67 316 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 317 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 318 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 319 | -1,-1,-1,-1, 34, -1}, // 68 320 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 321 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 322 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 323 | -1,-1,-1,-1, 37, -1}, // 69 324 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,70,-1, 325 | -1,-1,-1,-1,-1,-1,-1,-1,-1,46,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 326 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,46,-1,-1, 327 | -1,-1,-1,-1, 21, -1}, // 70 328 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,72,-1, 329 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 330 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 331 | -1,-1,-1,-1, -1, -1}, // 71 332 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,72,-1, 333 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 334 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 335 | -1,-1,-1,-1, 21, -1}, // 72 336 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 337 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 338 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 339 | -1,-1,-1,-1, 33, -1}, // 73 340 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 341 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 342 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 343 | -1,-1,-1,-1, 36, -1}, // 74 344 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 345 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 346 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 347 | -1,-1,-1,-1, 1, -1}, // 75 348 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 349 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 350 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 351 | -1,-1,-1,-1, 13, -1}, // 76 352 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 353 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 354 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 355 | -1,-1,-1,-1, 10, -1}, // 77 356 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 357 | -1,-1,-1,-1,-1,90,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 358 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 359 | -1,-1,-1,-1, 20, -1}, // 78 360 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 361 | -1,-1,-1,-1,-1,22,22,91,22,22,22,22,22,22,22,22,22,22,22,22, 362 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 363 | -1,-1,-1,-1, 20, -1}, // 79 364 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 365 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 366 | 22,22,22,92,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 367 | -1,-1,-1,-1, 20, -1}, // 80 368 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 369 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 370 | 22,22,93,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 371 | -1,-1,-1,-1, 20, -1}, // 81 372 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 373 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,94,22,22,22,22,22,22, 374 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 375 | -1,-1,-1,-1, 20, -1}, // 82 376 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 377 | -1,-1,-1,-1,-1,22,22,95,22,22,22,22,22,22,22,22,22,22,22,22, 378 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 379 | -1,-1,-1,-1, 20, -1}, // 83 380 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 381 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,96,22,22,22,22,22,22, 382 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 383 | -1,-1,-1,-1, 20, -1}, // 84 384 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 385 | -1,-1,-1,-1,-1,22,22,22,22,97,22,22,22,22,22,22,22,22,22,22, 386 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 387 | -1,-1,-1,-1, 20, -1}, // 85 388 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 389 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 390 | 22,22,22,22,98,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 391 | -1,-1,-1,-1, 20, -1}, // 86 392 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 393 | -1,-1,-1,-1,-1,22,22,22,22,99,22,22,22,22,22,22,22,22,22,22, 394 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 395 | -1,-1,-1,-1, 20, -1}, // 87 396 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 397 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,100,22, 398 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 399 | -1,-1,-1,-1, 20, -1}, // 88 400 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 401 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 402 | 22,101,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 403 | -1,-1,-1,-1, 20, -1}, // 89 404 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 405 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 406 | 22,22,22,102,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 407 | -1,-1,-1,-1, 20, -1}, // 90 408 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 409 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 410 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 411 | -1,-1,-1,-1, 11, -1}, // 91 412 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 413 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,103,22,22,22,22,22,22, 414 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 415 | -1,-1,-1,-1, 20, -1}, // 92 416 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 417 | -1,-1,-1,-1,-1,22,22,22,22,104,22,22,22,22,22,22,22,22,22,22, 418 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 419 | -1,-1,-1,-1, 20, -1}, // 93 420 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 421 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 422 | 22,22,22,105,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 423 | -1,-1,-1,-1, 20, -1}, // 94 424 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 425 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,106,22,22,22,22,22,22,22, 426 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 427 | -1,-1,-1,-1, 20, -1}, // 95 428 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 429 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,107,22, 430 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 431 | -1,-1,-1,-1, 20, -1}, // 96 432 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 433 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 434 | 22,108,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 435 | -1,-1,-1,-1, 20, -1}, // 97 436 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 437 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 438 | 22,109,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 439 | -1,-1,-1,-1, 20, -1}, // 98 440 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 441 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 442 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 443 | -1,-1,-1,-1, 15, -1}, // 99 444 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 445 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,110,22,22, 446 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 447 | -1,-1,-1,-1, 20, -1}, // 100 448 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 449 | -1,-1,-1,-1,-1,22,22,22,22,111,22,22,22,22,22,22,22,22,22,22, 450 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 451 | -1,-1,-1,-1, 20, -1}, // 101 452 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 453 | -1,-1,-1,-1,-1,22,22,22,22,112,22,22,22,22,22,22,22,22,22,22, 454 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 455 | -1,-1,-1,-1, 20, -1}, // 102 456 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 457 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,113,22,22, 458 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 459 | -1,-1,-1,-1, 20, -1}, // 103 460 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 461 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 462 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 463 | -1,-1,-1,-1, 16, -1}, // 104 464 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 465 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 466 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 467 | -1,-1,-1,-1, 12, -1}, // 105 468 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 469 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 470 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 471 | -1,-1,-1,-1, 0, -1}, // 106 472 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 473 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,114,22,22, 474 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 475 | -1,-1,-1,-1, 20, -1}, // 107 476 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 477 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 478 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 479 | -1,-1,-1,-1, 8, -1}, // 108 480 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 481 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,115,22,22, 482 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 483 | -1,-1,-1,-1, 20, -1}, // 109 484 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 485 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 486 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 487 | -1,-1,-1,-1, 2, -1}, // 110 488 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 489 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 490 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 491 | -1,-1,-1,-1, 7, -1}, // 111 492 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 493 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 494 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 495 | -1,-1,-1,-1, 3, -1}, // 112 496 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 497 | -1,-1,-1,-1,-1,22,22,116,22,22,22,22,22,22,22,22,22,22,22,22, 498 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 499 | -1,-1,-1,-1, 20, -1}, // 113 500 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 501 | -1,-1,-1,-1,-1,117,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 502 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 503 | -1,-1,-1,-1, 20, -1}, // 114 504 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 505 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 506 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 507 | -1,-1,-1,-1, 4, -1}, // 115 508 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 509 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 510 | 22,22,22,118,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 511 | -1,-1,-1,-1, 20, -1}, // 116 512 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 513 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,119,22,22,22,22, 514 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 515 | -1,-1,-1,-1, 20, -1}, // 117 516 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 517 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 518 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 519 | -1,-1,-1,-1, 6, -1}, // 118 520 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1, 521 | -1,-1,-1,-1,-1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 522 | 22,22,22,22,22,22,22,22,22,22,-1,-1,-1,-1,22,-1,22,22,22,-1, 523 | -1,-1,-1,-1, 17, -1}, // 119 524 | // 1 525 | {-1, 1, 1,-1, 1,-1,-1,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1, 526 | 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 527 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1, 528 | -1,-1,-1,-1, -1, -1}, // 0 529 | {-1, 1, 1,-1, 1,-1,-1,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1, 530 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 531 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1, 532 | -1,-1,-1,-1, -1, -1}, // 1 533 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 534 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 535 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 536 | -1,-1,-1,-1, 48, -1}, // 2 537 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 538 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 539 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 540 | -1,-1,-1,-1, 54, -1}, // 3 541 | // 2 542 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1, 543 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 544 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 545 | -1,-1,-1,-1, -1, -1}, // 0 546 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 547 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 548 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 549 | -1,-1,-1,-1, 49, -1}, // 1 550 | // 3 551 | {-1, 1, 1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 552 | 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 553 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1, 554 | -1,-1,-1,-1, -1, -1}, // 0 555 | {-1, 1, 1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 556 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 557 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1, 558 | -1,-1,-1,-1, -1, -1}, // 1 559 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 560 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 561 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 562 | -1,-1,-1,-1, 54, -1}, // 2 563 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 564 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 565 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 566 | -1,-1,-1,-1, 50, -1}, // 3 567 | // 4 568 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 569 | -1, 1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 570 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 571 | -1,-1,-1,-1, -1, -1}, // 0 572 | {-1, 1, 1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 2,-1,-1,-1,-1, 573 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 574 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 575 | -1,-1,-1,-1, -1, -1}, // 1 576 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 577 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 578 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 579 | -1,-1,-1,-1, 51, -1}, // 2 580 | // 5 581 | {-1, 1, 1,-1, 1,-1,-1,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1, 582 | 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 583 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 584 | -1,-1,-1,-1, -1, -1}, // 0 585 | {-1, 1, 1,-1, 1,-1,-1,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1, 586 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 587 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 588 | -1,-1,-1,-1, -1, -1}, // 1 589 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 590 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 591 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 592 | -1,-1,-1,-1, 52, -1}, // 2 593 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 594 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 595 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 596 | -1,-1,-1,-1, 54, -1}, // 3 597 | // 6 598 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 1,-1,-1,-1,-1, 599 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 600 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 601 | -1,-1,-1,-1, -1, -1}, // 0 602 | {-1, 1, 1,-1, 1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 603 | -1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 604 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 605 | -1,-1,-1,-1, -1, -1}, // 1 606 | {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 607 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 608 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 609 | -1,-1,-1,-1, 53, -1}, // 2 610 | }; 611 | 612 | 613 | int const (*ScannerBase::s_dfaBase__[])[66] = 614 | { 615 | s_dfa__ + 0, 616 | s_dfa__ + 120, 617 | s_dfa__ + 124, 618 | s_dfa__ + 126, 619 | s_dfa__ + 130, 620 | s_dfa__ + 133, 621 | s_dfa__ + 137, 622 | }; 623 | 624 | size_t ScannerBase::s_istreamNr = 0; 625 | 626 | // $insert inputImplementation 627 | ScannerBase::Input::Input() 628 | : 629 | d_in(0), 630 | d_lineNr(1) 631 | {} 632 | 633 | ScannerBase::Input::Input(std::istream *iStream, size_t lineNr) 634 | : 635 | d_in(iStream), 636 | d_lineNr(lineNr) 637 | {} 638 | 639 | size_t ScannerBase::Input::get() 640 | { 641 | switch (size_t ch = next()) // get the next input char 642 | { 643 | case '\n': 644 | ++d_lineNr; 645 | // FALLING THROUGH 646 | 647 | default: 648 | return ch; 649 | } 650 | } 651 | 652 | size_t ScannerBase::Input::next() 653 | { 654 | size_t ch; 655 | 656 | if (d_deque.empty()) // deque empty: next char fm d_in 657 | { 658 | if (d_in == 0) 659 | return AT_EOF; 660 | ch = d_in->get(); 661 | return *d_in ? ch : static_cast(AT_EOF); 662 | } 663 | 664 | ch = d_deque.front(); 665 | d_deque.pop_front(); 666 | 667 | return ch; 668 | } 669 | 670 | void ScannerBase::Input::reRead(size_t ch) 671 | { 672 | if (ch < 0x100) 673 | { 674 | if (ch == '\n') 675 | --d_lineNr; 676 | d_deque.push_front(ch); 677 | } 678 | } 679 | 680 | void ScannerBase::Input::reRead(std::string const &str, size_t fm) 681 | { 682 | for (size_t idx = str.size(); idx-- > fm; ) 683 | reRead(str[idx]); 684 | } 685 | 686 | ScannerBase::ScannerBase(std::istream &in, std::ostream &out) 687 | : 688 | d_filename("-"), 689 | d_out(new std::ostream(out.rdbuf())), 690 | // $insert interactiveInit 691 | d_in(0), 692 | d_input(new std::istream(in.rdbuf())), 693 | d_dfaBase__(s_dfa__) 694 | {} 695 | 696 | void ScannerBase::switchStream__(std::istream &in, size_t lineNr) 697 | { 698 | d_input.close(); 699 | d_input = Input(new std::istream(in.rdbuf()), lineNr); 700 | } 701 | 702 | 703 | ScannerBase::ScannerBase(std::string const &infilename, std::string const &outfilename) 704 | : 705 | d_filename(infilename), 706 | d_out(outfilename == "-" ? new std::ostream(std::cout.rdbuf()) : 707 | outfilename == "" ? new std::ostream(std::cerr.rdbuf()) : 708 | new std::ofstream(outfilename)), 709 | d_input(new std::ifstream(infilename)), 710 | d_dfaBase__(s_dfa__) 711 | {} 712 | 713 | void ScannerBase::switchStreams(std::istream &in, std::ostream &out) 714 | { 715 | switchStream__(in, 1); 716 | switchOstream(out); 717 | } 718 | 719 | 720 | void ScannerBase::switchOstream(std::ostream &out) 721 | { 722 | *d_out << std::flush; 723 | d_out.reset(new std::ostream(out.rdbuf())); 724 | } 725 | 726 | // $insert debugFunctions 727 | void ScannerBase::setDebug(bool onOff) 728 | {} 729 | 730 | bool ScannerBase::debug() const 731 | { 732 | return false; 733 | } 734 | 735 | void ScannerBase::redo(size_t nChars) 736 | { 737 | size_t from = nChars >= length() ? 0 : length() - nChars; 738 | d_input.reRead(d_matched, from); 739 | d_matched.resize(from); 740 | } 741 | 742 | void ScannerBase::switchOstream(std::string const &outfilename) 743 | { 744 | *d_out << std::flush; 745 | d_out.reset( 746 | outfilename == "-" ? new std::ostream(std::cout.rdbuf()) : 747 | outfilename == "" ? new std::ostream(std::cerr.rdbuf()) : 748 | new std::ofstream(outfilename)); 749 | } 750 | 751 | 752 | void ScannerBase::switchIstream(std::string const &infilename) 753 | { 754 | d_input.close(); 755 | d_filename = infilename; 756 | d_input = Input(new std::ifstream(infilename)); 757 | d_atBOL = true; 758 | } 759 | 760 | void ScannerBase::switchStreams(std::string const &infilename, 761 | std::string const &outfilename) 762 | { 763 | switchOstream(outfilename); 764 | switchIstream(infilename); 765 | } 766 | 767 | void ScannerBase::pushStream(std::istream &istr) 768 | { 769 | std::istream *streamPtr = new std::istream(istr.rdbuf()); 770 | p_pushStream("(istream)", streamPtr); 771 | } 772 | 773 | void ScannerBase::pushStream(std::string const &name) 774 | { 775 | std::istream *streamPtr = new std::ifstream(name); 776 | if (!*streamPtr) 777 | { 778 | delete streamPtr; 779 | throw std::runtime_error("Cannot read " + name); 780 | } 781 | p_pushStream(name, streamPtr); 782 | } 783 | 784 | 785 | void ScannerBase::p_pushStream(std::string const &name, std::istream *streamPtr) 786 | { 787 | if (d_streamStack.size() == s_maxSizeofStreamStack__) 788 | { 789 | delete streamPtr; 790 | throw std::length_error("Max stream stack size exceeded"); 791 | } 792 | 793 | d_streamStack.push_back(StreamStruct{d_filename, d_input}); 794 | d_filename = name; 795 | d_input = Input(streamPtr); 796 | d_atBOL = true; 797 | } 798 | 799 | bool ScannerBase::popStream() 800 | { 801 | d_input.close(); 802 | 803 | if (d_streamStack.empty()) 804 | return false; 805 | 806 | StreamStruct &top = d_streamStack.back(); 807 | 808 | d_input = top.pushedInput; 809 | d_filename = top.pushedName; 810 | d_streamStack.pop_back(); 811 | 812 | return true; 813 | } 814 | 815 | // $insert lopImplementation 816 | void ScannerBase::lop1__(int lopSC) 817 | { 818 | d_lopMatched = d_matched; 819 | d_lopPending = d_input.nPending(); 820 | 821 | d_lopEnd = d_lopMatched.end(); 822 | d_lopTail = d_lopEnd - 1; 823 | d_lopIter = d_lopTail; 824 | 825 | d_get = &ScannerBase::getLOP; 826 | 827 | d_lopSC = d_startCondition; // remember original SC 828 | begin(SC(lopSC)); // activate the 829 | // tail-matching SC 830 | } 831 | void ScannerBase::lop2__() // matched the tail 832 | { 833 | d_lopEnd = d_lopTail; // read the head 834 | d_lopIter = d_lopMatched.begin(); 835 | 836 | begin(SC(d_startCondition + 1)); // switch to the head-matching 837 | } // SC 838 | inline void ScannerBase::lop3__() // catch-all handler 839 | { 840 | d_lopIter = --d_lopTail; // increase the tail, try again 841 | } 842 | void ScannerBase::lop4__() 843 | { 844 | 845 | begin(SC(d_lopSC)); // restore original SC 846 | d_get = &ScannerBase::getInput; // restore get function 847 | 848 | d_input.setPending(d_lopPending); 849 | // reinsert the tail into the 850 | // input stream 851 | push(d_lopMatched.substr(length(), std::string::npos)); 852 | } 853 | size_t ScannerBase::getLOP() 854 | { 855 | size_t ch = d_lopIter == d_lopEnd ? as(AT_EOF) : *d_lopIter++; 856 | 857 | return ch; 858 | } 859 | 860 | 861 | // See the manual's section `Run-time operations' section for an explanation 862 | // of this member. 863 | ScannerBase::ActionType__ ScannerBase::actionType__(size_t range) 864 | { 865 | d_nextState = d_dfaBase__[d_state][range]; 866 | 867 | if (d_nextState != -1) // transition is possible 868 | return ActionType__::CONTINUE; 869 | 870 | if (knownFinalState()) // FINAL state reached 871 | return ActionType__::MATCH; 872 | 873 | if (d_matched.size()) 874 | return ActionType__::ECHO_FIRST; // no match, echo the 1st char 875 | 876 | return range != s_rangeOfEOF__ ? 877 | ActionType__::ECHO_CH 878 | : 879 | ActionType__::RETURN; 880 | } 881 | 882 | void ScannerBase::accept(size_t nChars) // old name: less 883 | { 884 | if (nChars < d_matched.size()) 885 | { 886 | d_input.reRead(d_matched, nChars); 887 | d_matched.resize(nChars); 888 | } 889 | } 890 | 891 | void ScannerBase::setMatchedSize(size_t length) 892 | { 893 | d_input.reRead(d_matched, length); // reread the tail section 894 | d_matched.resize(length); // return what's left 895 | } 896 | 897 | // At this point a rule has been matched. The next character is not part of 898 | // the matched rule and is sent back to the input. The final match length 899 | // is determined, the index of the matched rule is determined, and then 900 | // d_atBOL is updated. Finally the rule's index is returned. 901 | // The numbers behind the finalPtr assignments are explained in the 902 | // manual's `Run-time operations' section. 903 | size_t ScannerBase::matched__(size_t ch) 904 | { 905 | d_input.reRead(ch); 906 | 907 | FinalData *finalPtr; 908 | 909 | if (not d_atBOL) // not at BOL 910 | finalPtr = &d_final.std; // then use the std rule (3, 4) 911 | 912 | // at BOL 913 | else if (not available(d_final.std.rule)) // only a BOL rule avail. 914 | finalPtr = &d_final.bol; // use the BOL rule (6) 915 | 916 | else if (not available(d_final.bol.rule)) // only a std rule is avail. 917 | finalPtr = &d_final.std; // use the std rule (7) 918 | 919 | else if ( // Both are available (8) 920 | d_final.bol.length != // check lengths of matched texts 921 | d_final.std.length // unequal lengths, use the rule 922 | ) // having the longer match length 923 | finalPtr = 924 | d_final.bol.length > d_final.std.length ? 925 | &d_final.bol 926 | : 927 | &d_final.std; 928 | 929 | else // lengths are equal: use 1st rule 930 | finalPtr = 931 | d_final.bol.rule < d_final.std.rule ? 932 | &d_final.bol 933 | : 934 | &d_final.std; 935 | 936 | setMatchedSize(finalPtr->length); 937 | 938 | d_atBOL = d_matched.back() == '\n'; 939 | 940 | 941 | return finalPtr->rule; 942 | } 943 | 944 | size_t ScannerBase::getRange__(int ch) // using int to prevent casts 945 | { 946 | return ch == AT_EOF ? as(s_rangeOfEOF__) : s_ranges__[ch]; 947 | } 948 | 949 | // At this point d_nextState contains the next state and continuation is 950 | // possible. The just read char. is appended to d_match 951 | void ScannerBase::continue__(int ch) 952 | { 953 | d_state = d_nextState; 954 | 955 | if (ch != AT_EOF) 956 | d_matched += ch; 957 | } 958 | 959 | void ScannerBase::echoCh__(size_t ch) 960 | { 961 | *d_out << as(ch); 962 | d_atBOL = ch == '\n'; 963 | } 964 | 965 | 966 | // At this point there is no continuation. The last character is 967 | // pushed back into the input stream as well as all but the first char. in 968 | // the buffer. The first char. in the buffer is echoed to stderr. 969 | // If there isn't any 1st char yet then the current char doesn't fit any 970 | // rules and that char is then echoed 971 | void ScannerBase::echoFirst__(size_t ch) 972 | { 973 | d_input.reRead(ch); 974 | d_input.reRead(d_matched, 1); 975 | echoCh__(d_matched[0]); 976 | } 977 | 978 | // Update the rules associated with the current state, do this separately 979 | // for BOL and std rules. 980 | // If a rule was set, update the rule index and the current d_matched 981 | // length. 982 | void ScannerBase::updateFinals__() 983 | { 984 | size_t len = d_matched.size(); 985 | 986 | int const *rf = d_dfaBase__[d_state] + s_finIdx__; 987 | 988 | if (rf[0] != -1) // update to the latest std rule 989 | { 990 | d_final.std = FinalData { as(rf[0]), len }; 991 | } 992 | 993 | if (rf[1] != -1) // update to the latest bol rule 994 | { 995 | d_final.bol = FinalData { as(rf[1]), len }; 996 | } 997 | } 998 | 999 | void ScannerBase::reset__() 1000 | { 1001 | d_final = Final{ 1002 | FinalData{s_unavailable, 0}, 1003 | FinalData {s_unavailable, 0} 1004 | }; 1005 | 1006 | d_state = 0; 1007 | d_return = true; 1008 | 1009 | if (!d_more) 1010 | d_matched.clear(); 1011 | 1012 | d_more = false; 1013 | } 1014 | 1015 | int Scanner::executeAction__(size_t ruleIdx) 1016 | try 1017 | { 1018 | switch (ruleIdx) 1019 | { 1020 | // $insert actions 1021 | case 0: 1022 | { 1023 | #line 38 "lexer" 1024 | return Parser::MATCH; 1025 | } 1026 | break; 1027 | case 1: 1028 | { 1029 | #line 39 "lexer" 1030 | return Parser::ALL; 1031 | } 1032 | break; 1033 | case 2: 1034 | { 1035 | #line 40 "lexer" 1036 | return Parser::UNION; 1037 | } 1038 | break; 1039 | case 3: 1040 | { 1041 | #line 41 "lexer" 1042 | return Parser::CREATE; 1043 | } 1044 | break; 1045 | case 4: 1046 | { 1047 | #line 42 "lexer" 1048 | return Parser::RETURN; 1049 | } 1050 | break; 1051 | case 5: 1052 | { 1053 | #line 43 "lexer" 1054 | return Parser::AS; 1055 | } 1056 | break; 1057 | case 6: 1058 | { 1059 | #line 44 "lexer" 1060 | return Parser::DISTINCT; 1061 | } 1062 | break; 1063 | case 7: 1064 | { 1065 | #line 45 "lexer" 1066 | return Parser::WHERE; 1067 | } 1068 | break; 1069 | case 8: 1070 | { 1071 | #line 46 "lexer" 1072 | return Parser::ORDER; 1073 | } 1074 | break; 1075 | case 9: 1076 | { 1077 | #line 47 "lexer" 1078 | return Parser::BY; 1079 | } 1080 | break; 1081 | case 10: 1082 | { 1083 | #line 48 "lexer" 1084 | return Parser::ASC; 1085 | } 1086 | break; 1087 | case 11: 1088 | { 1089 | #line 49 "lexer" 1090 | return Parser::DESC; 1091 | } 1092 | break; 1093 | case 12: 1094 | { 1095 | #line 50 "lexer" 1096 | return Parser::LIMIT; 1097 | } 1098 | break; 1099 | case 13: 1100 | { 1101 | #line 51 "lexer" 1102 | return Parser::AND; 1103 | } 1104 | break; 1105 | case 14: 1106 | { 1107 | #line 52 "lexer" 1108 | return Parser::OR; 1109 | } 1110 | break; 1111 | case 15: 1112 | { 1113 | #line 53 "lexer" 1114 | return Parser::TRUE; 1115 | } 1116 | break; 1117 | case 16: 1118 | { 1119 | #line 54 "lexer" 1120 | return Parser::FALSE; 1121 | } 1122 | break; 1123 | case 17: 1124 | { 1125 | #line 55 "lexer" 1126 | return Parser::OPTIONAL; 1127 | } 1128 | break; 1129 | case 18: 1130 | { 1131 | #line 56 "lexer" 1132 | return Parser::INTEGER; 1133 | } 1134 | break; 1135 | case 20: 1136 | { 1137 | #line 58 "lexer" 1138 | return Parser::IDENTIFIER; 1139 | } 1140 | break; 1141 | case 21: 1142 | { 1143 | #line 60 "lexer" 1144 | return Parser::FLOAT; 1145 | } 1146 | break; 1147 | case 22: 1148 | { 1149 | #line 61 "lexer" 1150 | return Parser::STRING; 1151 | } 1152 | break; 1153 | case 23: 1154 | { 1155 | #line 62 "lexer" 1156 | return Parser::COMMA; 1157 | } 1158 | break; 1159 | case 24: 1160 | { 1161 | #line 63 "lexer" 1162 | return Parser::LEFT_PAREN; 1163 | } 1164 | break; 1165 | case 25: 1166 | { 1167 | #line 64 "lexer" 1168 | return Parser::RIGHT_PAREN; 1169 | } 1170 | break; 1171 | case 26: 1172 | { 1173 | #line 65 "lexer" 1174 | return Parser::LEFT_BRACKET; 1175 | } 1176 | break; 1177 | case 27: 1178 | { 1179 | #line 66 "lexer" 1180 | return Parser::RIGHT_BRACKET; 1181 | } 1182 | break; 1183 | case 28: 1184 | { 1185 | #line 67 "lexer" 1186 | return Parser::LEFT_CURLY_BRACKET; 1187 | } 1188 | break; 1189 | case 29: 1190 | { 1191 | #line 68 "lexer" 1192 | return Parser::RIGHT_CURLY_BRACKET; 1193 | } 1194 | break; 1195 | case 30: 1196 | { 1197 | #line 69 "lexer" 1198 | return Parser::GE; 1199 | } 1200 | break; 1201 | case 31: 1202 | { 1203 | #line 70 "lexer" 1204 | return Parser::LE; 1205 | } 1206 | break; 1207 | case 32: 1208 | { 1209 | #line 71 "lexer" 1210 | return Parser::EDGE; 1211 | } 1212 | break; 1213 | case 33: 1214 | { 1215 | #line 72 "lexer" 1216 | return Parser::LEFT_EDGE; 1217 | } 1218 | break; 1219 | case 34: 1220 | { 1221 | #line 73 "lexer" 1222 | return Parser::RIGHT_EDGE; 1223 | } 1224 | break; 1225 | case 38: 1226 | { 1227 | #line 77 "lexer" 1228 | return Parser::GT; 1229 | } 1230 | break; 1231 | case 39: 1232 | { 1233 | #line 78 "lexer" 1234 | return Parser::LT; 1235 | } 1236 | break; 1237 | case 40: 1238 | { 1239 | #line 79 "lexer" 1240 | return Parser::NE; 1241 | } 1242 | break; 1243 | case 41: 1244 | { 1245 | #line 80 "lexer" 1246 | return Parser::EQ; 1247 | } 1248 | break; 1249 | case 42: 1250 | { 1251 | #line 81 "lexer" 1252 | return Parser::COLON; 1253 | } 1254 | break; 1255 | case 43: 1256 | { 1257 | #line 82 "lexer" 1258 | return Parser::SEMICOLON; 1259 | } 1260 | break; 1261 | case 44: 1262 | { 1263 | #line 83 "lexer" 1264 | return Parser::DOT; 1265 | } 1266 | break; 1267 | case 45: 1268 | { 1269 | #line 84 "lexer" 1270 | return Parser::ASTERISK; 1271 | } 1272 | break; 1273 | case 46: 1274 | { 1275 | #line 85 "lexer" 1276 | return Parser::DOLLAR; 1277 | } 1278 | break; 1279 | case 47: 1280 | { 1281 | #line 86 "lexer" 1282 | return Parser::BAR; 1283 | } 1284 | break; 1285 | case 35: 1286 | { 1287 | lop1__(1); 1288 | } 1289 | break; 1290 | case 36: 1291 | { 1292 | lop1__(3); 1293 | } 1294 | break; 1295 | case 37: 1296 | { 1297 | lop1__(5); 1298 | } 1299 | break; 1300 | case 49: 1301 | { 1302 | #line 74 "lexer" 1303 | lop4__(); 1304 | return Parser::SHAFT; 1305 | } 1306 | break; 1307 | case 51: 1308 | { 1309 | #line 75 "lexer" 1310 | lop4__(); 1311 | return Parser::LEFT_ARROW; 1312 | } 1313 | break; 1314 | case 53: 1315 | { 1316 | #line 76 "lexer" 1317 | lop4__(); 1318 | return Parser::RIGHT_ARROW; 1319 | } 1320 | break; 1321 | case 50: 1322 | case 52: 1323 | case 48: 1324 | { 1325 | lop2__(); 1326 | } 1327 | break; 1328 | } 1329 | noReturn__(); 1330 | return 0; 1331 | } 1332 | catch (Leave__ value) 1333 | { 1334 | return static_cast(value); 1335 | } 1336 | 1337 | int Scanner::lex__() 1338 | { 1339 | reset__(); 1340 | preCode(); 1341 | 1342 | while (true) 1343 | { 1344 | size_t ch = get__(); // fetch next char 1345 | size_t range = getRange__(ch); // determine the range 1346 | 1347 | updateFinals__(); // update the state's Final info 1348 | 1349 | switch (actionType__(range)) // determine the action 1350 | { 1351 | case ActionType__::CONTINUE: 1352 | continue__(ch); 1353 | continue; 1354 | 1355 | case ActionType__::MATCH: 1356 | { 1357 | d_token__ = executeAction__(matched__(ch)); 1358 | if (return__()) 1359 | { 1360 | print(); 1361 | postCode(PostEnum__::RETURN); 1362 | return d_token__; 1363 | } 1364 | break; 1365 | } 1366 | 1367 | case ActionType__::ECHO_FIRST: 1368 | echoFirst__(ch); 1369 | break; 1370 | 1371 | case ActionType__::ECHO_CH: 1372 | echoCh__(ch); 1373 | break; 1374 | 1375 | case ActionType__::RETURN: 1376 | if (!popStream()) 1377 | { 1378 | postCode(PostEnum__::END); 1379 | return 0; 1380 | } 1381 | postCode(PostEnum__::POP); 1382 | continue; 1383 | } // switch 1384 | 1385 | postCode(PostEnum__::WIP); 1386 | 1387 | reset__(); 1388 | preCode(); 1389 | } // while 1390 | } 1391 | 1392 | void ScannerBase::print__() const 1393 | { 1394 | // $insert print 1395 | std::cout << "Token: " << d_token__; 1396 | if (isprint(d_token__)) 1397 | std::cout << " (`" << static_cast(d_token__) << "')"; 1398 | std::cout << ", matched: `" << d_matched << "'\n"; 1399 | } 1400 | 1401 | 1402 | -------------------------------------------------------------------------------- /src/scanner/lexer: -------------------------------------------------------------------------------- 1 | /* 2 | BSD 3-Clause License 3 | 4 | Copyright (c) 2017, expertcompsci 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | * Neither the name of the copyright holder nor the names of its 18 | contributors may be used to endorse or promote products derived from 19 | this software without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 25 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | %print-tokens 33 | 34 | WS [ \n\t] 35 | 36 | %% 37 | 38 | MATCH return Parser::MATCH; 39 | ALL return Parser::ALL; 40 | UNION return Parser::UNION; 41 | CREATE return Parser::CREATE; 42 | RETURN return Parser::RETURN; 43 | AS return Parser::AS; 44 | DISTINCT return Parser::DISTINCT; 45 | WHERE return Parser::WHERE; 46 | ORDER return Parser::ORDER; 47 | BY return Parser::BY; 48 | ASC return Parser::ASC; 49 | DESC return Parser::DESC; 50 | LIMIT return Parser::LIMIT; 51 | AND return Parser::AND; 52 | OR return Parser::OR; 53 | TRUE return Parser::TRUE; 54 | FALSE return Parser::FALSE; 55 | OPTIONAL return Parser::OPTIONAL; 56 | [0-9]+ return Parser::INTEGER; 57 | {WS}+ // skip white space chars. 58 | [[:alpha:]_][[:alpha:][:digit:]_]* return Parser::IDENTIFIER; 59 | // Float: opt sign, frac only | int only | frac and int, opt exp 60 | [-+]?([0-9]+(\.[0-9]+)?|\.[0-9]+)([eE][-+]?[0-9]+)? return Parser::FLOAT; 61 | "\""(.)*"\"" return Parser::STRING; 62 | \, return Parser::COMMA; 63 | \( return Parser::LEFT_PAREN; 64 | \) return Parser::RIGHT_PAREN; 65 | \[ return Parser::LEFT_BRACKET; 66 | \] return Parser::RIGHT_BRACKET; // right bracket must be escaped 67 | \{ return Parser::LEFT_CURLY_BRACKET; 68 | \} return Parser::RIGHT_CURLY_BRACKET; 69 | \>= return Parser::GE; 70 | \<= return Parser::LE; 71 | [-]{WS}*[-] return Parser::EDGE; 72 | [<]{WS}*[-]{WS}*[-] return Parser::LEFT_EDGE; 73 | [-]{WS}*[-]{WS}*[>] return Parser::RIGHT_EDGE; 74 | [-]/[\ \n\t]*[(\[] return Parser::SHAFT; 75 | [\<]{WS}*-/[\ \n\t]*[\[] return Parser::LEFT_ARROW; 76 | [\-]{WS}*\>/[\ \n\t]*[(] return Parser::RIGHT_ARROW; 77 | [>] return Parser::GT; 78 | [<] return Parser::LT; 79 | \!= return Parser::NE; 80 | \= return Parser::EQ; 81 | \: return Parser::COLON; 82 | \; return Parser::SEMICOLON; 83 | \. return Parser::DOT; 84 | \* return Parser::ASTERISK; 85 | \$ return Parser::DOLLAR; 86 | [\|] return Parser::BAR; 87 | ; 88 | -------------------------------------------------------------------------------- /starFieldGraphDb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/expertcompsci/embeddedCypher/e2734d9b59b8baa6ed5f725dfe5b7dc3df959e6f/starFieldGraphDb.jpg -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.6) 2 | 3 | find_package(GTest REQUIRED) 4 | include_directories(${GTEST_INCLUDE_DIRS} parser) 5 | 6 | add_executable(parserTestSuite ParserTestSuite.cpp) 7 | target_link_libraries(parserTestSuite ${GTEST_LIBRARIES} parser pthread) 8 | 9 | -------------------------------------------------------------------------------- /tests/ParserTestSuite.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | BSD 3-Clause License 3 | 4 | Copyright (c) 2017, expertcompsci 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | * Neither the name of the copyright holder nor the names of its 18 | contributors may be used to endorse or promote products derived from 19 | this software without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 25 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | #include 33 | #include "Parser.h" 34 | 35 | class ParserTestSuite : public testing::Test { 36 | protected: 37 | std::ostringstream oss; 38 | std::istringstream iss; 39 | 40 | void SetUp() { 41 | } 42 | 43 | void TearDown() { 44 | Parser parser(iss, oss); 45 | ASSERT_EQ(parser.parse(), 0); 46 | std::cout << oss.str(); 47 | } 48 | 49 | }; 50 | // Single node 51 | TEST_F(ParserTestSuite, matchEmptyNodeSpec) { 52 | iss.str("MATCH () RETURN *"); 53 | } 54 | TEST_F(ParserTestSuite, matchVarAndSingleLabelNodeSpec) { 55 | iss.str("MATCH (p:labelone:labeltwo) RETURN p"); 56 | } 57 | TEST_F(ParserTestSuite, matchNameLabelProperty) { 58 | iss.str("MATCH (p:labelone { name:'value' }) RETURN p"); 59 | } 60 | TEST_F(ParserTestSuite, matchNameLabelsProperty) { 61 | iss.str("MATCH (p:labelone:labeltwo { name:'value' }) RETURN p"); 62 | } 63 | TEST_F(ParserTestSuite, matchVarEQNode) { 64 | iss.str("MATCH p = () RETURN p"); 65 | } 66 | TEST_F(ParserTestSuite, matchVarEQNodeName) { 67 | iss.str("MATCH p = (x) RETURN p"); 68 | } 69 | TEST_F(ParserTestSuite, matchVarEQNameLabel) { 70 | iss.str("MATCH p = (x:labelone) RETURN p"); 71 | } 72 | TEST_F(ParserTestSuite, matchVarEQNameLabels) { 73 | iss.str("MATCH p = (x:labelone:labeltwo) RETURN p"); 74 | } 75 | TEST_F(ParserTestSuite, matchVarEQNameLabelsProperty) { 76 | iss.str("MATCH p = (x:labelone:labeltwo { name:'value' }) RETURN p"); 77 | } 78 | // Miscelaneous (never write openCypher like this!) 79 | TEST_F(ParserTestSuite, miscOne) { 80 | iss.str(R"( 81 | MATCH ( ) - 82 | [] - 83 | > 84 | ( p : 85 | labelone 86 | : labeltwo ) 87 | RETURN p 88 | )"); 89 | } 90 | TEST_F(ParserTestSuite, miscTwo) { 91 | iss.str(R"( 92 | MATCH ( ) - 93 | [] - 94 | ( p : 95 | labelone 96 | : labeltwo ) 97 | RETURN p 98 | )"); 99 | } 100 | // Multiple walks 101 | TEST_F(ParserTestSuite, multiOne) { 102 | iss.str("MATCH ()--()-->()<--() RETURN *"); 103 | } 104 | 105 | // Relationships node name 106 | TEST_F(ParserTestSuite, matchRel) { 107 | iss.str("MATCH ()--() RETURN *"); 108 | } 109 | TEST_F(ParserTestSuite, matchRelLeftNodeName) { 110 | iss.str("MATCH (p)--() RETURN *"); 111 | } 112 | TEST_F(ParserTestSuite, matchRelRightNodeName) { 113 | iss.str("MATCH ()--(p) RETURN *"); 114 | } 115 | TEST_F(ParserTestSuite, matchRightRel) { 116 | iss.str("MATCH ()-->() RETURN *"); 117 | } 118 | TEST_F(ParserTestSuite, matchRightRelLeftNodeName) { 119 | iss.str("MATCH (p)-->() RETURN *"); 120 | } 121 | TEST_F(ParserTestSuite, matchRightRelRightNodeName) { 122 | iss.str("MATCH ()-->(p) RETURN *"); 123 | } 124 | TEST_F(ParserTestSuite, matchLeftRel) { 125 | iss.str("MATCH ()<--() RETURN *"); 126 | } 127 | TEST_F(ParserTestSuite, matchLeftRelLeftNodeName) { 128 | iss.str("MATCH (p)<--() RETURN *"); 129 | } 130 | TEST_F(ParserTestSuite, matchLeftRelRightNodeName) { 131 | iss.str("MATCH ()<--(p) RETURN *"); 132 | } 133 | // Relationships node name and label 134 | TEST_F(ParserTestSuite, matchRightRelLeftNodeNameLabel) { 135 | iss.str("MATCH (p:labelone)-->() RETURN *"); 136 | } 137 | TEST_F(ParserTestSuite, matchRightRelRightNodeNameLabel) { 138 | iss.str("MATCH ()-->(p:labelone) RETURN *"); 139 | } 140 | TEST_F(ParserTestSuite, matchLeftRelLeftNodeNameLabel) { 141 | iss.str("MATCH (p:labelone)<--() RETURN *"); 142 | } 143 | TEST_F(ParserTestSuite, matchLeftRelRightNodeNameLabel) { 144 | iss.str("MATCH ()<--(p:labelone) RETURN *"); 145 | } 146 | // Relationship mulitiple nodes name and label 147 | TEST_F(ParserTestSuite, matchRelBothNodesNameLabel) { 148 | iss.str("MATCH (p:labelone)--(x:labeltwo) RETURN *"); 149 | } 150 | TEST_F(ParserTestSuite, matchRightRelBothNodesNameLabel) { 151 | iss.str("MATCH (p:labelone)-->(x:labeltwo) RETURN *"); 152 | } 153 | TEST_F(ParserTestSuite, matchLeftRelBothNodesNameLabel) { 154 | iss.str("MATCH (p:labelone)<--(x:labeltwo) RETURN *"); 155 | } 156 | // Relationship details undirected 157 | TEST_F(ParserTestSuite, matchRelDetail) { 158 | iss.str("MATCH ()-[]-() RETURN *"); 159 | } 160 | TEST_F(ParserTestSuite, matchRelDetailLeftNodeName) { 161 | iss.str("MATCH (p)-[]-() RETURN *"); 162 | } 163 | TEST_F(ParserTestSuite, matchRelDetailLeftNodeNameLabel) { 164 | iss.str("MATCH (p:labelone)-[]-() RETURN *"); 165 | } 166 | TEST_F(ParserTestSuite, matchRelDetailLabel) { 167 | iss.str("MATCH ()-[:R]-() RETURN *"); 168 | } 169 | TEST_F(ParserTestSuite, matchRelDetailLabelLeftNodeName) { 170 | iss.str("MATCH (p)-[:R]-() RETURN *"); 171 | } 172 | TEST_F(ParserTestSuite, matchRelDetailLabelLeftNodeNameLabel) { 173 | iss.str("MATCH (p:labelone)-[:R]-() RETURN *"); 174 | } 175 | TEST_F(ParserTestSuite, matchRelDetailLabelRightNodeName) { 176 | iss.str("MATCH ()-[:R]-(x) RETURN *"); 177 | } 178 | TEST_F(ParserTestSuite, matchRelDetailLabelRightNodeNameLabel) { 179 | iss.str("MATCH ()-[:R]-(x:labelone) RETURN *"); 180 | } 181 | TEST_F(ParserTestSuite, matchRelDetailLabelLeftNodeNameRightNodeNameLabel) { 182 | iss.str("MATCH (p)-[:R]-(x:labelone) RETURN *"); 183 | } 184 | TEST_F(ParserTestSuite, matchRelDetailLabelLeftNodeNameLabelRightNodeNameLabel) { 185 | iss.str("MATCH (p:labeltwo)-[:R]-(x:labelone) RETURN *"); 186 | } 187 | // Relationship details right 188 | TEST_F(ParserTestSuite, matchRightRelDetail) { 189 | iss.str("MATCH ()-[]->() RETURN *"); 190 | } 191 | TEST_F(ParserTestSuite, matchRightRelDetailLeftNodeName) { 192 | iss.str("MATCH (p)-[]->() RETURN *"); 193 | } 194 | TEST_F(ParserTestSuite, matchRightRelDetailLeftNodeNameLabel) { 195 | iss.str("MATCH (p:labelone)-[]->() RETURN *"); 196 | } 197 | TEST_F(ParserTestSuite, matchRightRelDetailLabel) { 198 | iss.str("MATCH ()-[:R]->() RETURN *"); 199 | } 200 | TEST_F(ParserTestSuite, matchRightRelDetailLabelLeftNodeName) { 201 | iss.str("MATCH (p)-[:R]->() RETURN *"); 202 | } 203 | TEST_F(ParserTestSuite, matchRightRelDetailLabelLeftNodeNameLabel) { 204 | iss.str("MATCH (p:labelone)-[:R]->() RETURN *"); 205 | } 206 | TEST_F(ParserTestSuite, matchRightRelDetailLabelRightNodeName) { 207 | iss.str("MATCH ()-[:R]->(x) RETURN *"); 208 | } 209 | TEST_F(ParserTestSuite, matchRightRelDetailLabelRightNodeNameLabel) { 210 | iss.str("MATCH ()-[:R]->(x:labelone) RETURN *"); 211 | } 212 | TEST_F(ParserTestSuite, matchRightRelDetailLabelLeftNodeNameRightNodeNameLabel) { 213 | iss.str("MATCH (p)-[:R]->(x:labelone) RETURN *"); 214 | } 215 | TEST_F(ParserTestSuite, matchRightRelDetailLabelLeftNodeNameLabelRightNodeNameLabel) { 216 | iss.str("MATCH (p:labeltwo)-[:R]->(x:labelone) RETURN *"); 217 | } 218 | // Relationship details left 219 | TEST_F(ParserTestSuite, matchLeftRelDetail) { 220 | iss.str("MATCH ()<-[]-() RETURN *"); 221 | } 222 | TEST_F(ParserTestSuite, matchLeftRelDetailLeftNodeName) { 223 | iss.str("MATCH (p)<-[]-() RETURN *"); 224 | } 225 | TEST_F(ParserTestSuite, matchLeftRelDetailLeftNodeNameLabel) { 226 | iss.str("MATCH (p:labelone)<-[]-() RETURN *"); 227 | } 228 | TEST_F(ParserTestSuite, matchLeftRelDetailLabel) { 229 | iss.str("MATCH ()<-[:R]-() RETURN *"); 230 | } 231 | TEST_F(ParserTestSuite, matchLeftRelDetailLabelLeftNodeName) { 232 | iss.str("MATCH (p)<-[:R]-() RETURN *"); 233 | } 234 | TEST_F(ParserTestSuite, matchLeftRelDetailLabelLeftNodeNameLabel) { 235 | iss.str("MATCH (p:labelone)<-[:R]-() RETURN *"); 236 | } 237 | TEST_F(ParserTestSuite, matchLeftRelDetailLabelRightNodeName) { 238 | iss.str("MATCH ()<-[:R]-(x) RETURN *"); 239 | } 240 | TEST_F(ParserTestSuite, matchLeftRelDetailLabelRightNodeNameLabel) { 241 | iss.str("MATCH ()<-[:R]-(x:labelone) RETURN *"); 242 | } 243 | TEST_F(ParserTestSuite, matchLeftRelDetailLabelLeftNodeNameRightNodeNameLabel) { 244 | iss.str("MATCH (p)<-[:R]-(x:labelone) RETURN *"); 245 | } 246 | TEST_F(ParserTestSuite, matchLeftRelDetailLabelLeftNodeNameLabelRightNodeNameLabel) { 247 | iss.str("MATCH (p:labeltwo)<-[:R]-(x:labelone) RETURN *"); 248 | } 249 | // Relationships label or label query undirected 250 | TEST_F(ParserTestSuite, matchRelOrLabel) { 251 | iss.str("MATCH ()-[:R | S]-() RETURN *"); 252 | } 253 | TEST_F(ParserTestSuite, matchRelOrLabelLeftNodeName) { 254 | iss.str("MATCH (p)-[:R | S]-() RETURN *"); 255 | } 256 | TEST_F(ParserTestSuite, matchRelOrLabelLeftNodeNameLabel) { 257 | iss.str("MATCH (p:labelone)-[:R | S]-() RETURN *"); 258 | } 259 | TEST_F(ParserTestSuite, matchRelOrLabelRightNodeName) { 260 | iss.str("MATCH ()-[:R | S]-(x) RETURN *"); 261 | } 262 | TEST_F(ParserTestSuite, matchRelOrLabelRightNodeNameLabel) { 263 | iss.str("MATCH ()-[:R | S]-(x:labelone) RETURN *"); 264 | } 265 | TEST_F(ParserTestSuite, matchRelOrLabelLeftNodeNameRightNodeNameLabel) { 266 | iss.str("MATCH (p)-[:R | S]-(x:labelone) RETURN *"); 267 | } 268 | TEST_F(ParserTestSuite, matchRelOrLabelLeftNodeNameLabelRightNodeNameLabel) { 269 | iss.str("MATCH (p:labeltwo)-[:R | S]-(x:labelone) RETURN *"); 270 | } 271 | // Relationships right label or label query undirected 272 | TEST_F(ParserTestSuite, matchRightRelOrLabel) { 273 | iss.str("MATCH ()-[:R | S]->() RETURN *"); 274 | } 275 | TEST_F(ParserTestSuite, matchRightRelOrLabelLeftNodeName) { 276 | iss.str("MATCH (p)-[:R | S]->() RETURN *"); 277 | } 278 | TEST_F(ParserTestSuite, matchRightRelOrLabelLeftNodeNameLabel) { 279 | iss.str("MATCH (p:labelone)-[:R | S]->() RETURN *"); 280 | } 281 | TEST_F(ParserTestSuite, matchRightRelOrLabelRightNodeName) { 282 | iss.str("MATCH ()-[:R | S]->(x) RETURN *"); 283 | } 284 | TEST_F(ParserTestSuite, matchRightRelOrLabelRightNodeNameLabel) { 285 | iss.str("MATCH ()-[:R | S]->(x:labelone) RETURN *"); 286 | } 287 | TEST_F(ParserTestSuite, matchRightRelOrLabelLeftNodeNameRightNodeNameLabel) { 288 | iss.str("MATCH (p)-[:R | S]->(x:labelone) RETURN *"); 289 | } 290 | TEST_F(ParserTestSuite, matchRightRelOrLabelLeftNodeNameLabelRightNodeNameLabel) { 291 | iss.str("MATCH (p:labeltwo)-[:R | S]->(x:labelone) RETURN *"); 292 | } 293 | // Relationships left label or label query undirected 294 | TEST_F(ParserTestSuite, matchLeftRelOrLabel) { 295 | iss.str("MATCH ()<-[:R | S]-() RETURN *"); 296 | } 297 | TEST_F(ParserTestSuite, matchLeftRelOrLabelLeftNodeName) { 298 | iss.str("MATCH (p)<-[:R | S]-() RETURN *"); 299 | } 300 | TEST_F(ParserTestSuite, matchLeftRelOrLabelLeftNodeNameLabel) { 301 | iss.str("MATCH (p:labelone)<-[:R | S]-() RETURN *"); 302 | } 303 | TEST_F(ParserTestSuite, matchLeftRelOrLabelRightNodeName) { 304 | iss.str("MATCH ()<-[:R | S]-(x) RETURN *"); 305 | } 306 | TEST_F(ParserTestSuite, matchLeftRelOrLabelRightNodeNameLabel) { 307 | iss.str("MATCH ()<-[:R | S]-(x:labelone) RETURN *"); 308 | } 309 | TEST_F(ParserTestSuite, matchLeftRelOrLabelLeftNodeNameRightNodeNameLabel) { 310 | iss.str("MATCH (p)<-[:R | S]-(x:labelone) RETURN *"); 311 | } 312 | TEST_F(ParserTestSuite, matchLeftRelOrLabelLeftNodeNameLabelRightNodeNameLabel) { 313 | iss.str("MATCH (p:labeltwo)<-[:R | S]-(x:labelone) RETURN *"); 314 | } 315 | 316 | int main(int argc, char **argv) { 317 | testing::InitGoogleTest(&argc, argv); 318 | return RUN_ALL_TESTS(); 319 | } 320 | --------------------------------------------------------------------------------