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/LexerDeclaratorParser.hpp>
  9 [cpp]#include <sng2html/sng2html/LexerIdentifierParser.hpp>
 10 [cpp]#include <sng2html/sng2html/LexerExpressionParser.hpp>
 11 [cpp]#include <sng2html/sng2html/LexerFileLexer.hpp>
 12 [cpp]#include <sng2html/sng2html/LexerFileTokens.hpp>
 13 
 14 using namespace soulng::lexer;
 15 using namespace LexerFileTokens;
 16 
 17 parser LexerDeclarationParser
 18 {
 19     uselexer LexerFileLexer;
 20 
 21     using LexerIdentifierParser.CppIdentifier;
 22     using LexerIdentifierParser.QualifiedCppId;
 23     using LexerDeclaratorParser.InitDeclaratorList;
 24     using LexerDeclaratorParser.TypeId;
 25     using LexerExpressionParser.AssignmentExpression;
 26 
 27     BlockDeclaration : soulng::cppcode::CppObject*
 28         ::= NamespaceAliasDefinition:nsAlias{ return nsAlias; }
 29         |   UsingDirective:usingDirective{ return usingDirective; }
 30         |   UsingDeclaration:usingDeclaration{ return usingDeclaration; }
 31         |   SimpleDeclaration:simpleDeclaration{ return simpleDeclaration; }
 32         ;
 33 
 34     SimpleDeclaration(var std::unique_ptr simpleDeclaration) : soulng::cppcode::SimpleDeclaration*
 35         ::= empty{ simpleDeclaration.reset(new soulng::cppcode::SimpleDeclaration()); }
 36             (DeclSpecifierSeq(simpleDeclaration.get()):declSpecifierSeq)?
 37             (InitDeclaratorList:initDeclaratorList{ simpleDeclaration->SetInitDeclaratorList(initDeclaratorList); })?
 38             SEMICOLON
 39         {
 40             return simpleDeclaration.release();
 41         }
 42         ;
 43 
 44     DeclSpecifierSeq(soulng::cppcode::SimpleDeclaration* declaration)
 45         ::= (DeclSpecifier:declSpecifier{ declaration->Add(declSpecifier); })+
 46         |   TypeName:typeName{ declaration->Add(typeName); }
 47         ;
 48 
 49     DeclSpecifier : soulng::cppcode::DeclSpecifier*
 50         ::= StorageClassSpecifier:storateClassSpecifier{ return storateClassSpecifier; }
 51         |   TypeSpecifier:typeSpecifier{ return typeSpecifier; }
 52         |   Typedef:tdef{ return tdef; }
 53         ;
 54 
 55     StorageClassSpecifier : soulng::cppcode::StorageClassSpecifier*
 56         ::= AUTO{ return new soulng::cppcode::StorageClassSpecifier(U"auto"); }
 57         |   REGISTER{ return new soulng::cppcode::StorageClassSpecifier(U"register"); }
 58         |   STATIC{ return new soulng::cppcode::StorageClassSpecifier(U"static"); }
 59         |   EXTERN{ return new soulng::cppcode::StorageClassSpecifier(U"extern"); }
 60         |   MUTABLE{ return new soulng::cppcode::StorageClassSpecifier(U"mutable"); }
 61         ;
 62 
 63     TypeSpecifier : soulng::cppcode::TypeSpecifier*
 64         ::= SimpleTypeSpecifier:simpleTypeSpecifier{ return simpleTypeSpecifier; }
 65         |   CVQualifier:cvQualified{ return cvQualified; }
 66         ;
 67 
 68     SimpleTypeSpecifier : soulng::cppcode::TypeSpecifier*
 69         ::= CHAR{ return new soulng::cppcode::TypeSpecifier(U"char"); }
 70         |   WCHART{ return new soulng::cppcode::TypeSpecifier(U"wchar_t"); }
 71         |   BOOL{ return new soulng::cppcode::TypeSpecifier(U"bool"); }
 72         |   SHORT{ return new soulng::cppcode::TypeSpecifier(U"short"); }
 73         |   INT{ return new soulng::cppcode::TypeSpecifier(U"int"); }
 74         |   LONG{ return new soulng::cppcode::TypeSpecifier(U"long"); }
 75         |   SIGNED{ return new soulng::cppcode::TypeSpecifier(U"signed"); }
 76         |   UNSIGNED{ return new soulng::cppcode::TypeSpecifier(U"unsigned"); }
 77         |   FLOAT{ return new soulng::cppcode::TypeSpecifier(U"float"); }
 78         |   DOUBLE{ return new soulng::cppcode::TypeSpecifier(U"double"); }
 79         |   VOID{ return new soulng::cppcode::TypeSpecifier(U"void"); }
 80         ;
 81 
 82     TypeName(var std::unique_ptr typeName) : soulng::cppcode::TypeName*
 83         ::=
 84         (
 85             QualifiedCppId:qid{ typeName.reset(new soulng::cppcode::TypeName(qid)); }
 86             (LANGLE{ ++lexer.leftAngleCount; typeName->IsTemplate() = true; } TemplateArgumentList(typeName.get()):args RANGLE{ --lexer.leftAngleCount; })?
 87         )
 88         {
 89             return typeName.release();
 90         }
 91         ;
 92 
 93     TemplateArgumentList(soulng::cppcode::TypeName* typeName)
 94         ::= TemplateArgument:arg{ typeName->AddTemplateArgument(arg); } % COMMA
 95         ;
 96 
 97     TemplateArgument : soulng::cppcode::CppObject*
 98         ::= TypeId:typeId{ return typeId; }
 99         |   AssignmentExpression:assignmentExpr{ return assignmentExpr; }
100         ;
101 
102     Typedef : soulng::cppcode::DeclSpecifier*
103         ::= TYPEDEF{ return new soulng::cppcode::Typedef(); }
104         ;
105 
106     CVQualifier : soulng::cppcode::TypeSpecifier*
107         ::= CONST{ return new soulng::cppcode::Const(); }
108         |   VOLATILE{ return new soulng::cppcode::Volatile(); }
109         ;
110 
111     NamespaceAliasDefinition : soulng::cppcode::UsingObject*
112         ::= (NAMESPACE CppIdentifier:id ASSIGN QualifiedCppId:qid SEMICOLON){ return new soulng::cppcode::NamespaceAlias(id, qid); }
113         ;
114 
115     UsingDeclaration : soulng::cppcode::UsingObject*
116         ::= USING QualifiedCppId:qid SEMICOLON{ return new soulng::cppcode::UsingDeclaration(qid); }
117         ;
118 
119     UsingDirective : soulng::cppcode::UsingObject*
120         ::= USING NAMESPACE QualifiedCppId:ns SEMICOLON{ return new soulng::cppcode::UsingDirective(ns); }
121         ;
122 
123     ruleinfo
124     {
125         (BlockDeclaration, "block declaration"), (SimpleDeclaration, "simple declaration"), (DeclSpecifierSeq, "declaration specifier sequence"),
126         (DeclSpecifier, "declaration specifier"), (StorageClassSpecifier, "storage class specifier"), (TypeSpecifier, "type specifier"),
127         (SimpleTypeSpecifier, "simple type specifier"), (TypeName, "type name"), (TemplateArgumentList, "template argument list"),
128         (TemplateArgument, "template argument"), (Typedef, "typedef specifier"), (CVQualifier, "const-volatile qualifier"),
129         (NamespaceAliasDefinition, "namespace alias definition"), (UsingDeclaration, "using declaration"), (UsingDirective, "using directive")
130     }
131 }