1 // =================================
  2 // Copyright (c) 2020 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 [hpp]#include <sng2html/sng2html/RegEx.hpp> 
  7 [hpp]#include <sng2html/sng2html/LexerContext.hpp>
  8 [hpp]#include <sng2html/sng2html/TokenValueParsers.hpp>
  9 [cpp]#include <sng2html/sng2html/RegExLexer.hpp>
 10 [cpp]#include <sng2html/sng2html/RegExTokens.hpp>
 11 
 12 using namespace soulng::lexer;
 13 using namespace RegExTokens;
 14 
 15 parser RegExParser
 16 {
 17     uselexer RegExLexer;
 18 
 19     main;
 20 
 21     RegularExpression(sng2html::sng2html::LexerContext* lexerContext) : sng2html::sng2html::RegExpression*
 22         ::= Alternative(lexerContext):alternative{ return alternative; }
 23         ;
 24 
 25     Alternative(sng2html::sng2html::LexerContext* lexerContext, var std::unique_ptr value) : sng2html::sng2html::RegExpression*
 26         ::= (Catenation(lexerContext):left{ value.reset(left); } (ALT Catenation(lexerContext):right!{ value.reset(new sng2html::sng2html::Alt(value.release(), right)); })*)
 27         {
 28             return value.release();
 29         }
 30         ;
 31 
 32     Catenation(sng2html::sng2html::LexerContext* lexerContext, var std::unique_ptr value) : sng2html::sng2html::RegExpression*
 33         ::= (Repetition(lexerContext):left{ value.reset(left); } (Repetition(lexerContext):right{ value.reset(new sng2html::sng2html::Cat(value.release(), right)); })*)
 34         {
 35             return value.release();
 36         }
 37         ;
 38 
 39     Repetition(sng2html::sng2html::LexerContext* lexerContext, var std::unique_ptr value) : sng2html::sng2html::RegExpression*
 40         ::=
 41         (   Primary(lexerContext):left{ value.reset(left); }
 42             (   STAR{ value.reset(new sng2html::sng2html::Kleene(value.release())); }
 43             |   PLUS{ value.reset(new sng2html::sng2html::Pos(value.release())); }
 44             |   QUEST{ value.reset(new sng2html::sng2html::Opt(value.release())); }
 45             )?
 46         )
 47         {
 48             return value.release();
 49         }
 50         ;
 51 
 52     Primary(sng2html::sng2html::LexerContext* lexerContext, var std::unique_ptr value) : sng2html::sng2html::RegExpression*
 53         ::=
 54         (   LPAREN Alternative(lexerContext):alt!{ value.reset(new sng2html::sng2html::ParenExpr(alt)); } RPAREN!
 55         |   ESCAPE{ value.reset(new sng2html::sng2html::SymbolExpr(lexerContext->MakeChar(sng2html::sng2html::MakeEscapeValue(lexer.FileName(), lexer.GetToken(pos))))); }
 56         |   INVERSE{ value.reset(new sng2html::sng2html::SymbolExpr(lexerContext->MakeChar('^'))); }
 57         |   MINUS{ value.reset(new sng2html::sng2html::SymbolExpr(lexerContext->MakeChar('-'))); }
 58         |   CHAR{ std::u32string match = lexer.GetMatch(span); value.reset(new sng2html::sng2html::SymbolExpr(lexerContext->MakeChar(match.front()))); }
 59         |   DOT{ value.reset(new sng2html::sng2html::SymbolExpr(lexerContext->MakeAny())); }
 60         |   Class(lexerContext):cls{ value.reset(new sng2html::sng2html::SymbolExpr(cls)); }
 61         |   ExpressionReference:ref{ value.reset(new sng2html::sng2html::RefExpr(ref)); }
 62         )
 63         {
 64             return value.release();
 65         }
 66         ;
 67 
 68     Class(sng2html::sng2html::LexerContext* lexerContext, var sng2html::sng2html::Class* cls) : sng2html::sng2html::Class*
 69         ::= (LBRACKET{ cls = lexerContext->MakeClass(); } ((INVERSE{ cls->SetInverse(); })? (Range(lexerContext):r{ cls->AddSymbol(r); })*) RBRACKET!)
 70         {
 71             return cls;
 72         }
 73         ;
 74 
 75     Range(sng2html::sng2html::LexerContext* lexerContext, var sng2html::sng2html::Symbol* symbol) : sng2html::sng2html::Symbol*
 76         ::= (Char:s (MINUS Char:e{ symbol = lexerContext->MakeRange(s, e); } | empty{ symbol = lexerContext->MakeChar(s); }))
 77         {
 78             return symbol;
 79         }
 80         ;
 81 
 82     Char : char32_t
 83         ::= LPAREN{ return '('; }
 84         |   RPAREN{ return ')'; }
 85         |   LBRACKET{ return '['; }
 86         |   LBRACE{ return '{'; }
 87         |   RBRACE{ return '}'; }
 88         |   ALT{ return '|'; }
 89         |   STAR{ return '*'; }
 90         |   PLUS{ return '+'; }
 91         |   QUEST{ return '?'; }
 92         |   DOT{ return '.'; }
 93         |   ESCAPE{ return sng2html::sng2html::MakeEscapeValue(lexer.FileName(), lexer.GetToken(pos)); }
 94         |   INVERSE{ return '^'; }
 95         |   MINUS{ return '-'; }
 96         |   CHAR{ std::u32string match = lexer.GetMatch(span); return match.front(); }
 97         ;
 98 
 99     ExpressionReference(var Span s) : std::u32string
100         ::= LBRACE{ s = span; } CHAR+ RBRACE{ s.end = span.end; return sng2html::sng2html::MakeExprRefId(lexer.FileName(), lexer.GetMatch(s), lexer.GetToken(pos).line); }
101         ;
102 
103     ruleinfo
104     {
105         (RegularExpression, "regular expression"), (Alternative, "alternative"), (Catenation, "catenation"), (Repetition, "repetition"), (Primary, "primary expression"),
106         (Class, "regular class definition"), (Range, "range"), (Char, "character"), (ExpressionReference, "regular expression reference")
107     }
108 }