|
| 1 | +# Parsing GraphQL Documents |
| 2 | + |
| 3 | +## PEGTL |
| 4 | + |
| 5 | +As mentioned in the [README](../README.md), `cppgraphqlgen` uses the |
| 6 | +[Parsing Expression Grammar Template Library (PEGTL)](https://github.com/taocpp/PEGTL) |
| 7 | +release 3.0.0, which is part of [The Art of C++](https://taocpp.github.io/) |
| 8 | +library collection. I've added this as a sub-module, so you do not need to |
| 9 | +install this separately. If you already have 3.0.0 installed where CMake can |
| 10 | +find it, it will use that instead of the sub-module and avoid installing |
| 11 | +another copy of PEGTL. _Note: PEGTL 3.0.0 is currently at pre-release._ |
| 12 | + |
| 13 | +It uses the [contrib/parse_tree.hpp](../PEGTL/include/tao/pegtl/contrib/parse_tree.hpp) |
| 14 | +module to build an AST automatically while parsing the document. The AST and |
| 15 | +the underlying grammar rules are tuned to the needs of `cppgraphqlgen`, but if |
| 16 | +you have another use for a GraphQL parser you could probably make a few small |
| 17 | +tweaks to include additional information in the rules or in the resulting AST. |
| 18 | +You could also use the grammar without the AST module if you want to handle |
| 19 | +the parsing callbacks another way. The grammar itself is defined in |
| 20 | +[GraphQLGrammar.h](../include/graphqlservice/GraphQLGrammar.h), and the AST |
| 21 | +selector callbacks are all defined in [GraphQLTree.cpp](../src/GraphQLTree.cpp). |
| 22 | +The grammar handles both the schema definition syntax which is used in |
| 23 | +`schemagen`, and the query/mutation/subscription operation syntax used in |
| 24 | +`Request::resolve` and `Request::subscribe`. |
| 25 | + |
| 26 | +## Utilities |
| 27 | + |
| 28 | +The [GraphQLParse.h](../include/graphqlservice/GraphQLParse.h) header includes |
| 29 | +several utility methods to help generate an AST from a `std::string_view` |
| 30 | +(`parseString`), an input file (`parseFile`), or using a |
| 31 | +[UDL](https://en.cppreference.com/w/cpp/language/user_literal) (`_graphql`) |
| 32 | +for hardcoded documents. |
| 33 | + |
| 34 | +The UDL is used throughout the sample unit tests and in `schemagen` for the |
| 35 | +hard-coded introspection schema. It will be useful for additional unit tests |
| 36 | +against your own custom schema. |
| 37 | + |
| 38 | +At runtime, you will probably call `parseString` most often to handle dynamic |
| 39 | +queries. If you have persisted queries saved to the file system or you are |
| 40 | +using a snapshot/[Approval Testing](https://approvaltests.com/) strategy you |
| 41 | +might also use `parseFile` to parse queries saved to text files. |
| 42 | + |
| 43 | +## Encoding |
| 44 | + |
| 45 | +The document must use a UTF-8 encoding. If you need to handle documents in |
| 46 | +another encoding you will need to convert them to UTF-8 before parsing. |
| 47 | + |
| 48 | +If you need to convert the encoding at runtime, I would recommend using |
| 49 | +`std::wstring_convert`, with the cavevat that it has been |
| 50 | +[deprecated](https://en.cppreference.com/w/cpp/locale/wstring_convert) in |
| 51 | +C++17. You could keep using it until it is replaced in the standard, you |
| 52 | +could use a portable non-standard library like |
| 53 | +[ICU](http://site.icu-project.org/design/cpp), or you could use |
| 54 | +platform-specific conversion routines like |
| 55 | +[WideCharToMultiByte](https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-widechartomultibyte) on Windows. |
0 commit comments