1 // =================================
  2 // Copyright (c) 2020 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 [hpp]#include <sng2html/sng2html/ParserFile.hpp>
  7 [cpp]#include <sng2html/sng2html/ParserIdentifierParser.hpp>
  8 [cpp]#include <sng2html/sng2html/ParserDeclaratorParser.hpp>
  9 [cpp]#include <sng2html/sng2html/ParserExpressionParser.hpp>
 10 [cpp]#include <sng2html/sng2html/ParserStatementParser.hpp>
 11 [cpp]#include <sng2html/sng2html/TokenValueParsers.hpp>
 12 [cpp]#include <sng2html/sng2html/ParserFileLexer.hpp>
 13 [cpp]#include <sng2html/sng2html/ParserFileTokens.hpp>
 14 
 15 using namespace soulng::lexer;
 16 using namespace ParserFileTokens;
 17 
 18 parser ParserFileParser
 19 {
 20     uselexer ParserFileLexer;
 21     main;
 22 
 23     using ParserIdentifierParser.QualifiedCppId;
 24     using ParserDeclaratorParser.TypeId;
 25     using ParserDeclaratorParser.Declarator;
 26     using ParserExpressionParser.ExpressionList;
 27     using ParserStatementParser.CompoundStatement;
 28 
 29     ParserFile(var std::unique_ptr parserFile) : sng2html::sng2html::ParserFile*
 30         ::= (empty{ parserFile.reset(new sng2html::sng2html::ParserFile(lexer.FileName())); } Declaration(parserFile.get()):declaration*)
 31         {
 32             return parserFile.release();
 33         }
 34         ;
 35 
 36     Declaration(sng2html::sng2html::ParserFile* parserFile)
 37         ::= IncludeDeclaration:includeDeclaration{ parserFile->AddInclude(includeDeclaration); }
 38         |   UsingNamespaceDeclaration:usingNamespaceDeclaration{ parserFile->AddUsingNamespace(usingNamespaceDeclaration); }
 39         |   ParserDeclaration:parserDeclaration{ parserFile->AddParser(parserDeclaration); }
 40         ;
 41 
 42     IncludeDeclaration(var bool prefix, var Span s) : sng2html::sng2html::Include*
 43         ::= empty{ lexer.parsingIncludeDeclaration = true; }
 44             ((IncludePrefix:includePrefix{ prefix = includePrefix; })? HASH{ s = span; } INCLUDE FILEPATH{ s.end = span.end; })
 45         {
 46             lexer.parsingIncludeDeclaration = false;
 47             return new sng2html::sng2html::Include(prefix, lexer.GetMatch(s));
 48         }
 49         /
 50         {
 51             lexer.parsingIncludeDeclaration = false;
 52         }
 53         ;
 54 
 55     IncludePrefix : bool
 56         ::= CPPPREFIX{ return false; }
 57         |   HPPPREFIX{ return true; }
 58         ;
 59 
 60     UsingNamespaceDeclaration(var Span s) : std::u32string
 61         ::= USING{ s = span; } NAMESPACE QualifiedCppId:ns SEMICOLON!{ s.end = span.end; return lexer.GetMatch(s); }
 62         ;
 63 
 64     ParserDeclaration(var std::unique_ptr grammarParser) : sng2html::sng2html::GrammarParser*
 65         ::= (PARSER Api:parserApi ID{ grammarParser.reset(new sng2html::sng2html::GrammarParser(lexer.GetMatch(span), parserApi)); } LBRACE! Statement(grammarParser.get()):statement* RBRACE!)
 66         {
 67             return grammarParser.release();
 68         }
 69         ;
 70 
 71     Api(var std::u32string id) : std::u32string
 72         ::= API LPAREN ID!{ id = lexer.GetMatch(span); } RPAREN!{ return id; }
 73         |   empty{ return std::u32string(); }
 74         ;
 75 
 76     Statement(sng2html::sng2html::GrammarParser* grammarParser)
 77         ::= MainStatement(grammarParser):mainStatement
 78         |   UsingStatement(grammarParser):usingStatement
 79         |   LexerStatement(grammarParser):lexerStatement
 80         |   RuleInfoStatement(grammarParser):ruleInfoStatement
 81         |   RuleStatement(grammarParser):ruleStatement
 82         ;
 83 
 84     MainStatement(sng2html::sng2html::GrammarParser* grammarParser)
 85         ::= MAIN SEMICOLON!{ grammarParser->SetMain(); }
 86         ;
 87 
 88     UsingStatement(sng2html::sng2html::GrammarParser* grammarParser)
 89         ::= USING UsingQualifiedId:parserId! SEMICOLON!{ grammarParser->AddUsing(parserId); }
 90         ;
 91 
 92     UsingQualifiedId(var Span s) : std::u32string
 93         ::= (ID{ s = span; } (DOT ID{ s.end = span.end; })*){ return lexer.GetMatch(s); }
 94         ;
 95 
 96     LexerStatement(sng2html::sng2html::GrammarParser* grammarParser, var std::u32string lexerName)
 97         ::= USELEXER ID!{ lexerName = lexer.GetMatch(span); } SEMICOLON!{ grammarParser->SetLexer(lexerName); }
 98         ;
 99 
100     RuleInfoStatement(sng2html::sng2html::GrammarParser* grammarParser)
101         ::= RULEINFO LBRACE! (RuleInfo(grammarParser):ruleInfo % COMMA)? RBRACE!
102         ;
103 
104     RuleInfo(sng2html::sng2html::GrammarParser* grammarParser, var std::u32string ruleName, var std::u32string ruleInfo)
105         ::= LPAREN ID!{ ruleName = lexer.GetMatch(span); } COMMA! STRINGLIT!{ ruleInfo = sng2html::sng2html::ParseStringLiteral(lexer.FileName(), lexer.GetToken(pos)); } RPAREN!
106         {
107             grammarParser->AddRuleInfo(ruleName, ruleInfo);
108         }
109         ;
110 
111     RuleStatement(sng2html::sng2html::GrammarParser* grammarParser, var std::unique_ptr rule)
112         ::= ID{ rule.reset(new sng2html::sng2html::RuleParser(lexer.GetMatch(span))); } ParametersAndVariables(rule.get()):paramsAndVars? ReturnType:returnType? PRODUCES RuleBody:definition! SEMICOLON!
113         {
114             rule->SetDefinition(definition);
115             rule->SetReturnType(returnType);
116             grammarParser->AddRule(rule.release());
117         }
118         ;
119 
120     ParametersAndVariables(sng2html::sng2html::RuleParser* rule)
121         ::= LPAREN (ParamOrVariable:paramOrVariable{ rule->AddParamOrVariable(paramOrVariable); } % COMMA)? RPAREN!
122         ;
123 
124     ParamOrVariable : sng2html::sng2html::Parameter*
125         ::= VAR TypeId:varType Declarator:varName{ return new sng2html::sng2html::Variable(varType, varName); }
126         |   TypeId:paramType Declarator:paramName{ return new sng2html::sng2html::Parameter(paramType, paramName); }
127         ;
128 
129     ReturnType : soulng::cppcode::TypeId*
130         ::= COLON TypeId:type{ return type; }
131         ;
132 
133     RuleBody : sng2html::sng2html::Parser*
134         ::= Alternative:alt{ return alt; }
135         ;
136 
137     Alternative(var std::unique_ptr value) : sng2html::sng2html::Parser*
138         ::= (Sequence:left{ value.reset(left); } (BITOR Sequence:right!{ value.reset(new sng2html::sng2html::AlternativeParser(value.release(), right)); })*)
139         {
140             return value.release();
141         }
142         ;
143 
144     Sequence(var std::unique_ptr value) : sng2html::sng2html::Parser*
145         ::= (Difference:left{ value.reset(left); } (Difference:right{ value.reset(new sng2html::sng2html::SequenceParser(value.release(), right)); })*)
146         {
147             return value.release();
148         }
149         ;
150 
151     Difference(var std::unique_ptr value) : sng2html::sng2html::Parser*
152         ::= (List:left{ value.reset(left); } (MINUS List:right!{ value.reset(new sng2html::sng2html::DifferenceParser(value.release(), right)); })*)
153         {
154             return value.release();
155         }
156         ;
157 
158     List(var std::unique_ptr value) : sng2html::sng2html::Parser*
159         ::= (Postfix:left{ value.reset(left); } (REM Postfix:right!{ value.reset(new sng2html::sng2html::ListParser(value.release(), right)); })?)
160         {
161             return value.release();
162         }
163         ;
164 
165     Postfix(var std::unique_ptr value) : sng2html::sng2html::Parser*
166         ::=
167         (   Primary:primary{ value.reset(primary); }
168             (   STAR{ value.reset(new sng2html::sng2html::KleeneParser(value.release())); }
169             |   PLUS{ value.reset(new sng2html::sng2html::PositiveParser(value.release())); }
170             |   QUEST{ value.reset(new sng2html::sng2html::OptionalParser(value.release())); }
171             )?    
172         )
173         {
174             return value.release();
175         }
176         ;
177 
178     Primary(var std::unique_ptr value) : sng2html::sng2html::Parser*
179         ::=
180         (
181             (   RuleCall:ruleCall{ value.reset(ruleCall); }
182             |   Primitive:primitive{ value.reset(primitive); }
183             |   Grouping:grouping{ value.reset(grouping); }
184             )
185             (
186                 EXCLAMATION{ value.reset(new sng2html::sng2html::ExpectationParser(value.release())); }
187             )?
188             (   
189                 (
190                     (CompoundStatement:successCode
191                     (DIV CompoundStatement:failureCode)?){ value.reset(new sng2html::sng2html::ActionParser(successCode, failureCode, value.release())); }
192                 )
193             )?
194         )
195         {
196             return value.release();
197         }
198         ;
199 
200     RuleCall(var std::u32string ruleName, var std::unique_ptr exprList, var int nonterminalPos) : sng2html::sng2html::Parser*
201         ::= Nonterminal:nt{ ruleName = nt; nonterminalPos = pos; }
202             (LPAREN{ pass = soulng::lexer::NoWhiteSpaceBetweenTokens(lexer.GetToken(nonterminalPos), lexer.GetToken(pos)); exprList.reset(new soulng::cppcode::ExpressionList()); }
203             ExpressionList(exprList.get()):args RPAREN)? COLON ID!
204         {
205             std::u32string name = lexer.GetMatch(span);
206             sng2html::sng2html::NonterminalParser* nonterminalParser = new sng2html::sng2html::NonterminalParser(name, ruleName);
207             nonterminalParser->SetArguments(exprList.get());
208             return nonterminalParser;
209         }
210         ;
211 
212     Nonterminal : std::u32string
213         ::= ID{ return lexer.GetMatch(span); }
214         ;
215 
216     Primitive : sng2html::sng2html::Parser*
217         ::= EMPTY{ return new sng2html::sng2html::EmptyParser(); }
218         |   ID{ return new sng2html::sng2html::TokenParser(lexer.GetMatch(span)); }
219         |   CHARLIT{ return new sng2html::sng2html::CharParser(sng2html::sng2html::ParseCharLiteral(lexer.FileName(), lexer.GetToken(pos))); }
220         |   STRINGLIT
221         {
222             std::u32string strLit = sng2html::sng2html::ParseStringLiteral(lexer.FileName(), lexer.GetToken(pos));
223             if (strLit.length() > 0 && strLit[0] == '[' && strLit[strLit.length() - 1] == ']')
224             {
225                 return new sng2html::sng2html::CharSetParser(sng2html::sng2html::ParseCharSet(lexer.FileName(), lexer.GetToken(pos), strLit));
226             }
227             else
228             {
229                 return new sng2html::sng2html::StringParser(strLit);
230             }
231         }
232         ;
233 
234     Grouping : sng2html::sng2html::Parser*
235         ::= (LPAREN Alternative:alt RPAREN!){ return new sng2html::sng2html::GroupingParser(alt); }
236         ;
237 }