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 #include <capnp/compiler/grammar.capnp.h>
25 #include <capnp/compiler/lexer.capnp.h>
26 #include <kj/parse/common.h>
27 #include <kj/arena.h>
28 #include "error-reporter.h"
29 
30 CAPNP_BEGIN_HEADER
31 
32 namespace capnp {
33 namespace compiler {
34 
35 void parseFile(List<Statement>::Reader statements, ParsedFile::Builder result,
36                ErrorReporter& errorReporter);
37 // Parse a list of statements to build a ParsedFile.
38 //
39 // If any errors are reported, then the output is not usable.  However, it may be passed on through
40 // later stages of compilation in order to detect additional errors.
41 
42 uint64_t generateRandomId();
43 // Generate a new random unique ID.  This lives here mostly for lack of a better location.
44 
45 uint64_t generateChildId(uint64_t parentId, kj::StringPtr childName);
46 // Generate the ID for a child node given its parent ID and name.
47 
48 uint64_t generateGroupId(uint64_t parentId, uint16_t groupIndex);
49 // Generate the ID for a group within a struct.
50 
51 uint64_t generateMethodParamsId(uint64_t parentId, uint16_t methodOrdinal, bool isResults);
52 // Generate the ID for a struct representing method params / results.
53 //
54 // TODO(cleanup):  Move generate*Id() somewhere more sensible.
55 
56 class CapnpParser {
57   // Advanced parser interface.  This interface exposes the inner parsers so that you can embed
58   // them into your own parsers.
59 
60 public:
61   CapnpParser(Orphanage orphanage, ErrorReporter& errorReporter);
62   // `orphanage` is used to allocate Cap'n Proto message objects in the result.  `inputStart` is
63   // a pointer to the beginning of the input, used to compute byte offsets.
64 
65   ~CapnpParser() noexcept(false);
66 
67   KJ_DISALLOW_COPY(CapnpParser);
68 
69   using ParserInput = kj::parse::IteratorInput<Token::Reader, List<Token>::Reader::Iterator>;
70   struct DeclParserResult;
71   template <typename Output>
72   using Parser = kj::parse::ParserRef<ParserInput, Output>;
73   using DeclParser = Parser<DeclParserResult>;
74 
75   kj::Maybe<Orphan<Declaration>> parseStatement(
76       Statement::Reader statement, const DeclParser& parser);
77   // Parse a statement using the given parser.  In addition to parsing the token sequence itself,
78   // this takes care of parsing the block (if any) and copying over the doc comment (if any).
79 
80   struct DeclParserResult {
81     // DeclParser parses a sequence of tokens representing just the "line" part of the statement --
82     // i.e. everything up to the semicolon or opening curly brace.
83     //
84     // Use `parseStatement()` to avoid having to deal with this struct.
85 
86     Orphan<Declaration> decl;
87     // The decl parsed so far.  The decl's `docComment` and `nestedDecls` are both empty at this
88     // point.
89 
90     kj::Maybe<DeclParser> memberParser;
91     // If null, the statement should not have a block.  If non-null, the statement should have a
92     // block containing statements parseable by this parser.
93 
DeclParserResultDeclParserResult94     DeclParserResult(Orphan<Declaration>&& decl, const DeclParser& memberParser)
95         : decl(kj::mv(decl)), memberParser(memberParser) {}
DeclParserResultDeclParserResult96     explicit DeclParserResult(Orphan<Declaration>&& decl)
97         : decl(kj::mv(decl)), memberParser(nullptr) {}
98   };
99 
100   struct Parsers {
101     DeclParser genericDecl;
102     // Parser that matches any declaration type except those that have ordinals (since they are
103     // context-dependent).
104 
105     DeclParser fileLevelDecl;
106     DeclParser enumLevelDecl;
107     DeclParser structLevelDecl;
108     DeclParser interfaceLevelDecl;
109     // Parsers that match genericDecl *and* the ordinal-based declaration types valid in the given
110     // contexts.  Note that these may match declarations that are not actually allowed in the given
111     // contexts, as long as the grammar is unambiguous.  E.g. nested types are not allowed in
112     // enums, but they'll be accepted by enumLevelDecl.  A later stage of compilation should report
113     // these as errors.
114 
115     Parser<Orphan<Expression>> expression;
116     Parser<Orphan<Declaration::AnnotationApplication>> annotation;
117     Parser<Orphan<LocatedInteger>> uid;
118     Parser<Orphan<LocatedInteger>> ordinal;
119     Parser<Orphan<Declaration::Param>> param;
120 
121     DeclParser usingDecl;
122     DeclParser constDecl;
123     DeclParser enumDecl;
124     DeclParser enumerantDecl;
125     DeclParser structDecl;
126     DeclParser fieldDecl;
127     DeclParser unionDecl;
128     DeclParser groupDecl;
129     DeclParser interfaceDecl;
130     DeclParser methodDecl;
131     DeclParser paramDecl;
132     DeclParser annotationDecl;
133     // Parsers for individual declaration types.
134   };
135 
getParsers()136   const Parsers& getParsers() { return parsers; }
137 
138 private:
139   Orphanage orphanage;
140   ErrorReporter& errorReporter;
141   kj::Arena arena;
142   Parsers parsers;
143 };
144 
145 kj::String expressionString(Expression::Reader name);
146 // Stringify the expression as code.
147 
148 }  // namespace compiler
149 }  // namespace capnp
150 
151 CAPNP_END_HEADER
152