1 | // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors |
2 | // Licensed under the MIT License: |
3 | // |
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy |
5 | // of this software and associated documentation files (the "Software"), to deal |
6 | // in the Software without restriction, including without limitation the rights |
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
8 | // copies of the Software, and to permit persons to whom the Software is |
9 | // furnished to do so, subject to the following conditions: |
10 | // |
11 | // The above copyright notice and this permission notice shall be included in |
12 | // all copies or substantial portions of the Software. |
13 | // |
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
20 | // THE SOFTWARE. |
21 | |
22 | #pragma once |
23 | |
24 | #if defined(__GNUC__) && !defined(CAPNP_HEADER_WARNINGS) |
25 | #pragma GCC system_header |
26 | #endif |
27 | |
28 | #include <capnp/compiler/grammar.capnp.h> |
29 | #include <capnp/compiler/lexer.capnp.h> |
30 | #include <kj/parse/common.h> |
31 | #include <kj/arena.h> |
32 | #include "error-reporter.h" |
33 | |
34 | namespace capnp { |
35 | namespace compiler { |
36 | |
37 | void parseFile(List<Statement>::Reader statements, ParsedFile::Builder result, |
38 | ErrorReporter& errorReporter); |
39 | // Parse a list of statements to build a ParsedFile. |
40 | // |
41 | // If any errors are reported, then the output is not usable. However, it may be passed on through |
42 | // later stages of compilation in order to detect additional errors. |
43 | |
44 | uint64_t generateRandomId(); |
45 | // Generate a new random unique ID. This lives here mostly for lack of a better location. |
46 | |
47 | uint64_t generateChildId(uint64_t parentId, kj::StringPtr childName); |
48 | // Generate the ID for a child node given its parent ID and name. |
49 | |
50 | uint64_t generateGroupId(uint64_t parentId, uint16_t groupIndex); |
51 | // Generate the ID for a group within a struct. |
52 | |
53 | uint64_t generateMethodParamsId(uint64_t parentId, uint16_t methodOrdinal, bool isResults); |
54 | // Generate the ID for a struct representing method params / results. |
55 | // |
56 | // TODO(cleanup): Move generate*Id() somewhere more sensible. |
57 | |
58 | class CapnpParser { |
59 | // Advanced parser interface. This interface exposes the inner parsers so that you can embed |
60 | // them into your own parsers. |
61 | |
62 | public: |
63 | CapnpParser(Orphanage orphanage, ErrorReporter& errorReporter); |
64 | // `orphanage` is used to allocate Cap'n Proto message objects in the result. `inputStart` is |
65 | // a pointer to the beginning of the input, used to compute byte offsets. |
66 | |
67 | ~CapnpParser() noexcept(false); |
68 | |
69 | KJ_DISALLOW_COPY(CapnpParser); |
70 | |
71 | using ParserInput = kj::parse::IteratorInput<Token::Reader, List<Token>::Reader::Iterator>; |
72 | struct DeclParserResult; |
73 | template <typename Output> |
74 | using Parser = kj::parse::ParserRef<ParserInput, Output>; |
75 | using DeclParser = Parser<DeclParserResult>; |
76 | |
77 | kj::Maybe<Orphan<Declaration>> parseStatement( |
78 | Statement::Reader statement, const DeclParser& parser); |
79 | // Parse a statement using the given parser. In addition to parsing the token sequence itself, |
80 | // this takes care of parsing the block (if any) and copying over the doc comment (if any). |
81 | |
82 | struct DeclParserResult { |
83 | // DeclParser parses a sequence of tokens representing just the "line" part of the statement -- |
84 | // i.e. everything up to the semicolon or opening curly brace. |
85 | // |
86 | // Use `parseStatement()` to avoid having to deal with this struct. |
87 | |
88 | Orphan<Declaration> decl; |
89 | // The decl parsed so far. The decl's `docComment` and `nestedDecls` are both empty at this |
90 | // point. |
91 | |
92 | kj::Maybe<DeclParser> memberParser; |
93 | // If null, the statement should not have a block. If non-null, the statement should have a |
94 | // block containing statements parseable by this parser. |
95 | |
96 | DeclParserResult(Orphan<Declaration>&& decl, const DeclParser& memberParser) |
97 | : decl(kj::mv(decl)), memberParser(memberParser) {} |
98 | explicit DeclParserResult(Orphan<Declaration>&& decl) |
99 | : decl(kj::mv(decl)), memberParser(nullptr) {} |
100 | }; |
101 | |
102 | struct Parsers { |
103 | DeclParser genericDecl; |
104 | // Parser that matches any declaration type except those that have ordinals (since they are |
105 | // context-dependent). |
106 | |
107 | DeclParser fileLevelDecl; |
108 | DeclParser enumLevelDecl; |
109 | DeclParser structLevelDecl; |
110 | DeclParser interfaceLevelDecl; |
111 | // Parsers that match genericDecl *and* the ordinal-based declaration types valid in the given |
112 | // contexts. Note that these may match declarations that are not actually allowed in the given |
113 | // contexts, as long as the grammar is unambiguous. E.g. nested types are not allowed in |
114 | // enums, but they'll be accepted by enumLevelDecl. A later stage of compilation should report |
115 | // these as errors. |
116 | |
117 | Parser<Orphan<Expression>> expression; |
118 | Parser<Orphan<Declaration::AnnotationApplication>> annotation; |
119 | Parser<Orphan<LocatedInteger>> uid; |
120 | Parser<Orphan<LocatedInteger>> ordinal; |
121 | Parser<Orphan<Declaration::Param>> param; |
122 | |
123 | DeclParser usingDecl; |
124 | DeclParser constDecl; |
125 | DeclParser enumDecl; |
126 | DeclParser enumerantDecl; |
127 | DeclParser structDecl; |
128 | DeclParser fieldDecl; |
129 | DeclParser unionDecl; |
130 | DeclParser groupDecl; |
131 | DeclParser interfaceDecl; |
132 | DeclParser methodDecl; |
133 | DeclParser paramDecl; |
134 | DeclParser annotationDecl; |
135 | // Parsers for individual declaration types. |
136 | }; |
137 | |
138 | const Parsers& getParsers() { return parsers; } |
139 | |
140 | private: |
141 | Orphanage orphanage; |
142 | ErrorReporter& errorReporter; |
143 | kj::Arena arena; |
144 | Parsers parsers; |
145 | }; |
146 | |
147 | } // namespace compiler |
148 | } // namespace capnp |
149 | |