1 // =================================
  2 // Copyright (c) 2020 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 [hpp]#include <sngcm/cmparser/ParserApi.hpp>
  7 [hpp]#include <sngcm/ast/CompileUnit.hpp>
  8 [hpp]#include <sngcm/cmparser/ParsingContext.hpp>
  9 [hpp]#include <memory>
 10 [cpp]#include <sngcm/cmparser/Typedef.hpp>
 11 [cpp]#include <sngcm/cmparser/Identifier.hpp>
 12 [cpp]#include <sngcm/cmparser/Concept.hpp>
 13 [cpp]#include <sngcm/cmparser/Function.hpp>
 14 [cpp]#include <sngcm/cmparser/Class.hpp>
 15 [cpp]#include <sngcm/cmparser/Interface.hpp>
 16 [cpp]#include <sngcm/cmparser/Enumeration.hpp>
 17 [cpp]#include <sngcm/cmparser/Constant.hpp>
 18 [cpp]#include <sngcm/cmparser/Delegate.hpp>
 19 [cpp]#include <sngcm/cmparser/GlobalVariable.hpp>
 20 [cpp]#include <sngcm/cmlexer/CmajorLexer.hpp>
 21 [cpp]#include <sngcm/cmlexer/CmajorTokens.hpp>
 22 
 23 using namespace sngcm::ast;
 24 using namespace CmajorTokens;
 25 
 26 parser api(SNGCM_PARSER_API) CompileUnitParser
 27 {
 28     main;
 29     uselexer CmajorLexer;
 30 
 31     using IdentifierParser.Identifier;
 32     using IdentifierParser.QualifiedId;
 33     using ConceptParser.Concept;
 34     using FunctionParser.Function;
 35     using ClassParser.Class;
 36     using InterfaceParser.Interface;
 37     using TypedefParser.Typedef;
 38     using EnumerationParser.EnumType;
 39     using ConstantParser.Constant;
 40     using DelegateParser.Delegate;
 41     using DelegateParser.ClassDelegate;
 42     using GlobalVariableParser.GlobalVariable;
 43 
 44     CompileUnit(ParsingContext* ctx, var std::unique_ptr compileUnit) : sngcm::ast::CompileUnitNode*
 45         ::= empty{ compileUnit.reset(new CompileUnitNode(span, lexer.FileName())); }
 46             NamespaceContent(ctx, compileUnit.get(), compileUnit->GlobalNs()):content{ return compileUnit.release(); }
 47         ;
 48 
 49     NamespaceContent(ParsingContext* ctx, sngcm::ast::CompileUnitNode* cu, sngcm::ast::NamespaceNode* ns)
 50         ::= UsingDirectives(ctx, ns):usingDirectives
 51             Definitions(ctx, cu, ns):definitions
 52         ;
 53 
 54     UsingDirectives(ParsingContext* ctx, sngcm::ast::NamespaceNode* ns)
 55         ::= UsingDirective(ctx, ns):usingDirective*
 56         ;
 57 
 58     UsingDirective(ParsingContext* ctx, sngcm::ast::NamespaceNode* ns)
 59         ::= UsingAliasDirective:usingAlias{ ns->AddMember(usingAlias); }
 60         |   UsingNamespaceDirective(ctx):usingNs{ ns->AddMember(usingNs); }
 61         ;
 62 
 63     UsingAliasDirective(var Span s) : Node*
 64         ::= USING{ s = span; } Identifier:id ASSIGN QualifiedId:qid! SEMICOLON!
 65         {
 66             s.end = span.end;
 67             return new AliasNode(s, id, qid);
 68         }
 69         ;
 70 
 71     UsingNamespaceDirective(ParsingContext* ctx, var Span s) : Node*
 72         ::= USING{ s = span; } QualifiedId:ns! SEMICOLON!
 73         {
 74             s.end = span.end;
 75             return new NamespaceImportNode(s, ns);
 76         }
 77         ;
 78 
 79     Definitions(ParsingContext* ctx, sngcm::ast::CompileUnitNode* cu, sngcm::ast::NamespaceNode* ns)
 80         ::= (Definition(ctx, cu, ns):definition{ ns->AddMember(definition); })*
 81         ;
 82 
 83     Definition(ParsingContext* ctx, sngcm::ast::CompileUnitNode* cu, sngcm::ast::NamespaceNode* ns) : Node*
 84         ::= NamespaceDefinition(ctx, cu, ns):nsDefinition{ return nsDefinition; }
 85         |   TypedefDeclaration(ctx):typedefDeclaration{ return typedefDeclaration; }
 86         |   ConceptDefinition(ctx):conceptDefinition{ return conceptDefinition; }
 87         |   FunctionDefinition(ctx):functionDefinition{ return functionDefinition; }
 88         |   ClassDefinition(ctx):classDefinition{ return classDefinition; }
 89         |   InterfaceDefinition(ctx):interfaceDefinition{ return interfaceDefinition; }
 90         |   EnumTypeDefinition(ctx):enumTypeDefinition{ return enumTypeDefinition; }
 91         |   ConstantDefinition(ctx):constantDefinition{ return constantDefinition; }
 92         |   DelegateDefinition(ctx):delegateDefinition{ return delegateDefinition; }
 93         |   ClassDelegateDefinition(ctx):classDelegateDefinition{ return classDelegateDefinition; }
 94         |   GlobalVariableDefinition(ctx, cu):globalVariableDefinition{ return globalVariableDefinition; }
 95         ;
 96 
 97     NamespaceDefinition(ParsingContext* ctx, sngcm::ast::CompileUnitNode* cu, sngcm::ast::NamespaceNode* ns, var std::unique_ptr nsNode, var Span s) : NamespaceNode*
 98         ::= NAMESPACE{ s = span; } (QualifiedId:nsName{ s.end = span.end; nsNode.reset(new NamespaceNode(s, nsName)); } | empty{ nsNode.reset(new NamespaceNode(s, nullptr)); })
 99             LBRACE! NamespaceContent(ctx, cu, nsNode.get()):content! RBRACE!
100         {
101             return nsNode.release();
102         }
103         ;
104 
105     TypedefDeclaration(ParsingContext* ctx) : TypedefNode*
106         ::= Typedef(ctx):typedefDeclaration{ return typedefDeclaration; }
107         ;
108 
109     ConceptDefinition(ParsingContext* ctx) : ConceptNode*
110         ::= Concept(ctx):conceptDefinition{ return conceptDefinition; }
111         ;
112 
113     FunctionDefinition(ParsingContext* ctx) : FunctionNode*
114         ::= Function(ctx):functionDefinition{ return functionDefinition; }
115         ;
116 
117     ClassDefinition(ParsingContext* ctx) : ClassNode*
118         ::= Class(ctx):classDefinition{ return classDefinition; }
119         ;
120 
121     InterfaceDefinition(ParsingContext* ctx) : InterfaceNode*
122         ::= Interface(ctx):interfaceDefinition{ return interfaceDefinition; }
123         ;
124 
125     EnumTypeDefinition(ParsingContext* ctx) : EnumTypeNode*
126         ::= EnumType(ctx):enumTypeDefinition{ return enumTypeDefinition; }
127         ;
128 
129     ConstantDefinition(ParsingContext* ctx) : ConstantNode*
130         ::= Constant(ctx):constantDefinition{ return constantDefinition; }
131         ;
132 
133     DelegateDefinition(ParsingContext* ctx) : DelegateNode*
134         ::= Delegate(ctx):delegateDefinition{ return delegateDefinition; }
135         ;
136 
137     ClassDelegateDefinition(ParsingContext* ctx) : ClassDelegateNode*
138         ::= ClassDelegate(ctx):classDelegateDefinition{ return classDelegateDefinition; }
139         ;
140 
141     GlobalVariableDefinition(ParsingContext* ctx, sngcm::ast::CompileUnitNode* cu) : GlobalVariableNode*
142         ::= GlobalVariable(ctx, cu):globalVariableDefinition{ return globalVariableDefinition; }
143         ;
144 
145     ruleinfo
146     {
147         (CompileUnit, "compile unit"), (NamespaceContent, "namespace content"), (UsingDirectives, "using directives"), (UsingDirective, "using directive"),
148         (UsingAliasDirective, "using alias directive"), (UsingNamespaceDirective, "using namespace directive"), (Definitions, "definitions"),
149         (Definition, "definition"), (NamespaceDefinition, "namespace definition"), (TypedefDeclaration , "typedef declaration"), (ConceptDefinition, "concept definition"),
150         (FunctionDefinition, "function definition"), (ClassDefinition, "class definition"), (InterfaceDefinition, "interface definition"), (EnumTypeDefinition, "enumerated type definition"),
151         (ConstantDefinition, "constant definition"), (DelegateDefinition, "delegate definition"), (ClassDelegateDefinition, "class delegate definition"),
152         (GlobalVariableDefinition, "global variable definition")
153     }
154 }
155 
156