1 // =================================
  2 // Copyright (c) 2020 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 [hpp]#include <sngcpp/pp/PP.hpp>
  7 [cpp]#include <sngcpp/pp/PPLexer.hpp>
  8 [cpp]#include <sngcpp/pp/PPTokens.hpp>
  9 
 10 using namespace PPTokens;
 11 
 12 parser api(SNGCPP_PP_API) PPLineParser
 13 {
 14     uselexer PPLexer;
 15     main;
 16 
 17     PPLine(sngcpp::pp::PP* pp)
 18         ::= Define(pp):defineLine
 19         |   Include(pp):includeLine
 20         |   If(pp):ifLine
 21         |   Ifdef(pp):ifdefLine
 22         |   Ifndef(pp):ifndefLine
 23         |   Elif(pp):elifLine
 24         |   Else(pp):elseLine
 25         |   Endif(pp):endifLine
 26         |   Other(pp):otherLine
 27         ;
 28 
 29     Define(sngcpp::pp::PP* pp, var std::vector* tokens)
 30         ::= (HASH DEFINE ID{ soulng::lexer::Token id = lexer.GetToken(pos); tokens = pp->BeginDefine(id.match); } PPToken(tokens):ppToken*)
 31         {
 32             pp->EndDefine(*tokens);
 33         }
 34         ;
 35 
 36     Include(sngcpp::pp::PP* pp, var bool isAngleHeader, var std::string headerName)
 37         ::= HASH INCLUDE
 38         (   ANGLEHEADERNAME{ isAngleHeader = true; soulng::lexer::Token headerNameToken = lexer.GetToken(pos); headerName = sngcpp::pp::ParseAngleHeaderName(lexer.FileName(), headerNameToken); }
 39         |   QUOTEHEADERNAME{ isAngleHeader = false; soulng::lexer::Token headerNameToken = lexer.GetToken(pos); headerName = sngcpp::pp::ParseQuoteHeaderName(lexer.FileName(), headerNameToken); }
 40         )
 41         {
 42             pp->Include(isAngleHeader, headerName);
 43         }
 44         ;
 45 
 46     If(sngcpp::pp::PP* pp, var std::vector exprTokens)
 47         ::=
 48         (
 49             HASH IF PPToken(&exprTokens):ppToken*
 50         )
 51         {
 52             pp->If(exprTokens);
 53         }
 54         ;
 55 
 56     Ifdef(sngcpp::pp::PP* pp, var bool defined)
 57         ::=
 58         (
 59             HASH IFDEF ID{ soulng::lexer::Token token = lexer.GetToken(pos); defined = pp->IsDefined(token.match); }
 60         )
 61         {
 62             pp->Ifdef(defined);
 63         }
 64         ;
 65 
 66     Ifndef(sngcpp::pp::PP* pp, var bool defined)
 67         ::= 
 68         (
 69             HASH IFNDEF ID{ soulng::lexer::Token token = lexer.GetToken(pos); defined = pp->IsDefined(token.match); }
 70         )
 71         {
 72             pp->Ifndef(defined);
 73         }
 74         ;
 75 
 76     Elif(sngcpp::pp::PP* pp, var std::vector exprTokens)
 77         ::=
 78         (
 79             HASH ELIF PPToken(&exprTokens):ppToken*
 80         )
 81         {
 82             pp->Elif(exprTokens);
 83         }
 84         ;
 85 
 86     Else(sngcpp::pp::PP* pp)
 87         ::=
 88         (
 89             HASH ELSE
 90         )
 91         {
 92             pp->Else();
 93         }
 94         ;
 95 
 96     Endif(sngcpp::pp::PP* pp)
 97         ::=
 98         (
 99             HASH ENDIF
100         )
101         {
102             pp->Endif();
103         }
104         ;
105 
106     Other(sngcpp::pp::PP* pp)
107         ::=
108         (
109             HASH PPToken(nullptr):ppToken*
110         )
111         ;
112 
113     PPToken(std::vector* tokens) : int*
114         ::= ID{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
115         |   DEFINED{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
116         |   ANGLEHEADERNAME{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
117         |   QUOTEHEADERNAME{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
118         |   PPNUMBER{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
119         |   CHARLITERAL{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
120         |   STRINGLITERAL{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
121         |   CHAR{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
122         |   COLONCOLON{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
123         |   COMMA{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
124         |   ASSIGN{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
125         |   MULASSIGN{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
126         |   DIVASSIGN{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
127         |   REMASSIGN{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
128         |   ADDASSIGN{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
129         |   SUBASSIGN{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
130         |   SHIFTRIGHTASSIGN{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
131         |   SHIFTLEFTASSIGN{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
132         |   ANDASSIGN{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
133         |   XORASSIGN{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
134         |   ORASSIGN{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
135         |   QUEST{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
136         |   COLON{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
137         |   OROR{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
138         |   AMPAMP{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
139         |   OR{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
140         |   XOR{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
141         |   AMP{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
142         |   EQ{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
143         |   NEQ{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
144         |   LEQ{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
145         |   GEQ{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
146         |   SPACESHIP{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
147         |   LANGLE{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
148         |   RANGLE{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
149         |   SHIFTLEFT{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
150         |   SHIFTRIGHT{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
151         |   PLUS{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
152         |   MINUS{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
153         |   STAR{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
154         |   DIV{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
155         |   MOD{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
156         |   DOTSTAR{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
157         |   ARROWSTAR{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
158         |   LPAREN{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
159         |   RPAREN{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
160         |   PLUSPLUS{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
161         |   MINUSMINUS{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
162         |   EXCLAMATION{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
163         |   TILDE{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
164         |   LBRACKET{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
165         |   RBRACKET{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
166         |   DOT{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
167         |   ARROW{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
168         |   SEMICOLON{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
169         |   ELLIPSES{ if (tokens) tokens->push_back(lexer.GetToken(pos)); return nullptr; }
170         ;
171 }