1 // =================================
  2 // Copyright (c) 2020 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 [hpp]#include <soulng/cppcode/Declaration.hpp>
  7 [hpp]#include <soulng/cppcode/Type.hpp>
  8 [cpp]#include <sng2html/sng2html/LexerExpressionParser.hpp>
  9 [cpp]#include <sng2html/sng2html/LexerDeclarationParser.hpp>
 10 [cpp]#include <sng2html/sng2html/LexerFileLexer.hpp>
 11 [cpp]#include <sng2html/sng2html/LexerFileTokens.hpp>
 12 [cpp]#include <soulng/util/TextUtils.hpp>
 13 
 14 using namespace soulng::lexer;
 15 using namespace LexerFileTokens;
 16 
 17 parser LexerDeclaratorParser
 18 {
 19     uselexer LexerFileLexer;
 20 
 21     using LexerExpressionParser.ConstantExpression;
 22     using LexerExpressionParser.IdExpression;
 23     using LexerExpressionParser.ExpressionList;
 24     using LexerExpressionParser.AssignmentExpression;
 25     using LexerDeclarationParser.TypeName;
 26     using LexerDeclarationParser.TypeSpecifier;
 27     using LexerDeclarationParser.CVQualifier;
 28 
 29     InitDeclaratorList(var std::unique_ptr initDeclaratorList) : soulng::cppcode::InitDeclaratorList*
 30         ::=
 31         (   empty{ initDeclaratorList.reset(new soulng::cppcode::InitDeclaratorList()); }
 32             (InitDeclarator:initDeclarator{ initDeclaratorList->Add(initDeclarator); } % COMMA)
 33         )
 34         {
 35             return initDeclaratorList.release();
 36         }
 37         ;
 38 
 39     InitDeclarator : soulng::cppcode::InitDeclarator*
 40         ::= (Declarator:declarator Initializer:initializer?)
 41         {
 42             return new soulng::cppcode::InitDeclarator(declarator, initializer);
 43         }
 44         ;
 45 
 46     Declarator(var Span s) : std::u32string
 47         ::=
 48         (   DirectDeclarator:directDeclarator{ s = span; }
 49         |   PtrOperator:ptrOperator{ s = span; } Declarator:declarator{ s.end = span.end; }
 50         )
 51         {
 52             return lexer.GetMatch(s);
 53         }
 54         ;
 55 
 56     DirectDeclarator
 57         ::= DeclaratorId:declaratorId
 58         (   LBRACKET ConstantExpression:expr? RBRACKET
 59         |   LPAREN Declarator:declarator RPAREN
 60         )*
 61         ;
 62 
 63     DeclaratorId
 64         ::= IdExpression:idExpr
 65         |   TypeName:typeName
 66         ;
 67 
 68     TypeId(var std::unique_ptr typeId) : soulng::cppcode::TypeId*
 69         ::= empty{ typeId.reset(new soulng::cppcode::TypeId()); }
 70         (
 71             (TypeSpecifierSeq(typeId.get()):typeSpecifierSeq | TypeName:typeName{ typeId->Add(typeName); })
 72             (AbstractDeclarator:abstractDeclarator{ typeId->Declarator() = abstractDeclarator; })?
 73         )
 74         {
 75             return typeId.release();
 76         }
 77         ;
 78 
 79     Type(var std::unique_ptr type) : soulng::cppcode::Type*
 80         ::= empty{ type.reset(new soulng::cppcode::Type()); }
 81         (   (TypeSpecifier:typeSpecifier{ type->Add(typeSpecifier); })+
 82         |   TypeName:typeName{ type->Add(typeName); }
 83         )
 84         {
 85             return type.release();
 86         }
 87         ;
 88 
 89     TypeSpecifierSeq(soulng::cppcode::TypeId* typeId)
 90         ::= (TypeSpecifier:typeSpecifier{ typeId->Add(typeSpecifier); })+
 91         ;
 92 
 93     AbstractDeclarator(var Span s) : std::u32string
 94         ::= 
 95         (   PtrOperator:ptrOperator{ s = span; } (AbstractDeclarator:abstractDeclarator{ s.end = span.end; })?
 96         |   DirectAbstractDeclarator:directAbstractDeclarator{ s = span; }
 97         )
 98         {
 99             return soulng::util::Trim(lexer.GetMatch(s));
100         }
101         ;
102 
103     DirectAbstractDeclarator
104         ::=
105         (   LBRACKET ConstantExpression:expr? RBRACKET
106         |   LPAREN AbstractDeclarator:abstractDeclarator RPAREN
107         )+
108         ;
109 
110     PtrOperator
111         ::= STAR CVQualifierSeq:cvQualifiedSeq?
112         |   AMP
113         ;
114 
115     CVQualifierSeq
116         ::= CVQualifier:cvQualifier+
117         ;
118 
119     Initializer(var std::unique_ptr initializer) : soulng::cppcode::Initializer*
120         ::=
121         (   ASSIGN InitializerClause:initializerClause{ initializer.reset(new soulng::cppcode::Initializer(initializerClause)); }
122         |   LPAREN{ initializer.reset(new soulng::cppcode::Initializer(nullptr)); } ExpressionList(initializer.get()):exprList RPAREN
123         )
124         {
125             return initializer.release();
126         }
127         ;
128 
129     InitializerClause(var std::unique_ptr assignInit) : soulng::cppcode::AssignInit*
130         ::=
131         (   AssignmentExpression:expr{ assignInit.reset(new soulng::cppcode::AssignInit(expr)); }
132         |   LBRACE{ assignInit.reset(new soulng::cppcode::AssignInit(nullptr)); } InitializerList(assignInit.get()):initializerList RBRACE
133         |   LBRACE RBRACE{ assignInit.reset(new soulng::cppcode::AssignInit(nullptr)); }
134         )
135         {
136             return assignInit.release();
137         }
138         ;
139 
140     InitializerList(soulng::cppcode::AssignInit* init)
141         ::= InitializerClause:initializerClause{ init->Add(initializerClause); } % COMMA
142         ;
143 
144     ruleinfo
145     {
146         (InitDeclaratorList, "initializer declarator list"), (InitDeclarator, "initializer declarator"), (Declarator, "declarator"), (DirectDeclarator, "direct declarator"),
147         (DeclaratorId, "declarator identifier"), (TypeId, "type identifier"), (Type, "type"), (TypeSpecifierSeq, "type specifier sequence"), (AbstractDeclarator, "abstract declarator"),
148         (DirectAbstractDeclarator, "direct abstract declarator"), (PtrOperator, "pointer operator"), (CVQualifierSeq, "const-volatile qualifier sequence"), (Initializer, "initializer"),
149         (InitializerClause, "initializer clause"), (InitializerList, "initializer list")
150     }
151 }