1 // =================================
 2 // Copyright (c) 2021 Seppo Laakko
 3 // Distributed under the MIT license
 4 // =================================
 5 
 6 [hpp]#include <sngcm/cmparser/ParserApi.hpp>
 7 [hpp]#include <sngcm/ast/Function.hpp>
 8 [hpp]#include <sngcm/cmparser/ParsingContext.hpp>
 9 [cpp]#include <sngcm/cmlexer/CmajorLexer.hpp>
10 [cpp]#include <sngcm/cmlexer/CmajorTokens.hpp>
11 [cpp]#include <sngcm/cmparser/Attribute.hpp>
12 [cpp]#include <sngcm/cmparser/Specifier.hpp>
13 [cpp]#include <sngcm/cmparser/TypeExpr.hpp>
14 [cpp]#include <sngcm/cmparser/Concept.hpp>
15 [cpp]#include <sngcm/cmparser/Identifier.hpp>
16 [cpp]#include <sngcm/cmparser/Template.hpp>
17 [cpp]#include <sngcm/cmparser/Parameter.hpp>
18 [cpp]#include <sngcm/cmparser/Statement.hpp>
19 
20 using namespace sngcm::ast;
21 using namespace CmajorTokens;
22 
23 parser api(SNGCM_PARSER_API) FunctionParser
24 {
25     uselexer CmajorLexer;
26 
27     using AttributeParser.Attributes;
28     using SpecifierParser.Specifiers;
29     using TypeExprParser.TypeExpr;
30     using TemplateParser.TemplateParameterList;
31     using ConceptParser.WhereConstraint;
32     using ParameterParser.ParameterList;
33     using IdentifierParser.Identifier;
34     using StatementParser.CompoundStatement;
35 
36     Function(boost::uuids::uuid* moduleId, ParsingContext* ctx, var std::unique_ptr fun, var Span s, var Span specifierSpan) : FunctionNode*
37         ::= empty{ s = span; } Attributes(moduleId):attrs? Specifiers:specifiers{ specifierSpan = span; } TypeExpr(moduleId, ctx):returnType FunctionGroupId(moduleId, ctx):functionGroupId
38         {
39             s.end = span.end;
40             fun.reset(new FunctionNode(s, *moduleId, specifiers, returnType, functionGroupId, attrs));
41             fun->SetSpecifierSpan(specifierSpan);
42             fun->SetGroupIdSpan(span);
43         }
44         TemplateParameterList(moduleId, ctx, fun.get()):templateParams?
45         ParameterList(moduleId, ctx, fun.get()):paramList
46         (WhereConstraint(moduleId, ctx):constraint{ fun->SetConstraint(constraint); })?
47         (CompoundStatement(moduleId, ctx):body{ fun->SetBody(body); } | SEMICOLON)
48         {
49             return fun.release();
50         }
51         ;
52 
53     FunctionGroupId(boost::uuids::uuid* moduleId, ParsingContext* ctx) : std::u32string
54         ::= ID{ return lexer.GetMatch(span); }
55         |   OperatorFunctionGroupId(moduleId, ctx):operatorFunctionGroupId{ return operatorFunctionGroupId; }
56         ;
57 
58     OperatorFunctionGroupId(boost::uuids::uuid* moduleId, ParsingContext* ctx) : std::u32string
59         ::= empty{ lexer.parsingOperatorFunctionGroupId = true; }
60         (   OPERATOR
61             (   ((LANGLE LANGLE) - (LANGLE LANGLE (TypeExpr(moduleId, ctx):typeExpr % COMMA) RANGLE)){ lexer.parsingOperatorFunctionGroupId = false; return U"operator<<"; }
62             |   SHIFTRIGHT{ lexer.parsingOperatorFunctionGroupId = false; return U"operator>>"; }
63             |   EQ{ lexer.parsingOperatorFunctionGroupId = false; return U"operator=="; }
64             |   ASSIGN{ lexer.parsingOperatorFunctionGroupId = false; return U"operator="; }
65             |   LANGLE{ lexer.parsingOperatorFunctionGroupId = false; return U"operator<"; }
66             |   ARROW{ lexer.parsingOperatorFunctionGroupId = false; return U"operator->"; }
67             |   PLUSPLUS{ lexer.parsingOperatorFunctionGroupId = false; return U"operator++"; }
68             |   MINUSMINUS{ lexer.parsingOperatorFunctionGroupId = false; return U"operator--"; }
69             |   PLUS{ lexer.parsingOperatorFunctionGroupId = false; return U"operator+"; }
70             |   MINUS{ lexer.parsingOperatorFunctionGroupId = false; return U"operator-"; }
71             |   STAR{ lexer.parsingOperatorFunctionGroupId = false; return U"operator*"; }
72             |   DIV{ lexer.parsingOperatorFunctionGroupId = false; return U"operator/"; }
73             |   REM{ lexer.parsingOperatorFunctionGroupId = false; return U"operator%"; }
74             |   AMP{ lexer.parsingOperatorFunctionGroupId = false; return U"operator&"; }
75             |   BITOR{ lexer.parsingOperatorFunctionGroupId = false; return U"operator|"; }
76             |   BITXOR{ lexer.parsingOperatorFunctionGroupId = false; return U"operator^"; }
77             |   EXCLAMATION{ lexer.parsingOperatorFunctionGroupId = false; return U"operator!"; }
78             |   CPL{ lexer.parsingOperatorFunctionGroupId = false; return U"operator~"; }
79             |   LBRACKET RBRACKET{ lexer.parsingOperatorFunctionGroupId = false; return U"operator[]"; }
80             |   LPAREN RPAREN{ lexer.parsingOperatorFunctionGroupId = false; return U"operator()"; }
81             )
82         )
83         {
84             lexer.parsingOperatorFunctionGroupId = false;
85         }
86         /
87         {
88             lexer.parsingOperatorFunctionGroupId = false;
89         }
90         ;
91 
92     ruleinfo
93     {
94         (Function, "function"), (FunctionGroupId, "function group identifier"), (OperatorFunctionGroupId, "operator function group identifier")
95     }
96 }