Skip to content

Commit 6eca5ff

Browse files
committed
Write content for parsing.md
1 parent e328177 commit 6eca5ff

File tree

1 file changed

+55
-0
lines changed

1 file changed

+55
-0
lines changed

doc/parsing.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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

Comments
 (0)