1 // =================================
  2 // Copyright (c) 2020 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 [hpp]#include <sng2html/sng2html/LexerFile.hpp>
  7 [cpp]#include <sng2html/sng2html/TokenValueParsers.hpp>
  8 [cpp]#include <sng2html/sng2html/LexerDeclaratorParser.hpp>
  9 [cpp]#include <sng2html/sng2html/LexerStatementParser.hpp>
 10 [cpp]#include <sng2html/sng2html/LexerFileLexer.hpp>
 11 [cpp]#include <sng2html/sng2html/LexerFileTokens.hpp>
 12 
 13 using namespace soulng::lexer;
 14 using namespace LexerFileTokens;
 15 
 16 parser LexerFileParser
 17 {
 18     uselexer LexerFileLexer;
 19 
 20     using LexerDeclaratorParser.TypeId;
 21     using LexerStatementParser.CompoundStatement;
 22 
 23     main;
 24 
 25     LexerFile(var std::unique_ptr lexerFile) : sng2html::sng2html::LexerFile*
 26         ::= empty{ lexerFile.reset(new sng2html::sng2html::LexerFile()); }
 27         (
 28             (Declaration:declaration{ lexerFile->Add(declaration); })*
 29         )
 30         {
 31             return lexerFile.release();
 32         }
 33         ;
 34 
 35     Declaration : sng2html::sng2html::Declaration*
 36         ::= ClassMap:classMapDeclaration{ return classMapDeclaration; }
 37         |   Prefix:prefixDeclaration{ return prefixDeclaration; }
 38         |   Include:includeDeclaration{ return includeDeclaration; }
 39         |   Tokens:tokensDeclaration{ return tokensDeclaration; }
 40         |   Keywords:keywordsDeclaration{ return keywordsDeclaration; }
 41         |   Expressions:expressionsDeclaration{ return expressionsDeclaration; }
 42         |   Lexer:lexerDeclaration{ return lexerDeclaration; }
 43         ;
 44 
 45     ClassMap(var std::u32string classMapName) : sng2html::sng2html::ClassMap*
 46         ::= CLASSMAP ID!{ classMapName = lexer.GetMatch(span); } SEMICOLON!{ return new sng2html::sng2html::ClassMap(classMapName); }
 47         ;
 48 
 49     Prefix : sng2html::sng2html::Prefix*
 50         ::= PREFIX STRINGLIT! SEMICOLON!{ return new sng2html::sng2html::Prefix(U""); }
 51         ;
 52 
 53     Include : sng2html::sng2html::IncludeDeclaration*
 54         ::= HASH INCLUDE FILEPATH!{ return new sng2html::sng2html::IncludeDeclaration(U""); }
 55         ;
 56 
 57     Tokens(var std::u32string tokensDeclarationName, var std::unique_ptr tokens) : sng2html::sng2html::Tokens*
 58         ::= TOKENS ID!{ tokensDeclarationName = lexer.GetMatch(span); } LBRACE!{ tokens.reset(new sng2html::sng2html::Tokens(tokensDeclarationName)); }
 59             (Token:token{ tokens->Add(token); } % COMMA)? RBRACE!
 60         {
 61             return tokens.release();
 62         }
 63         ;
 64 
 65     Token(var std::u32string tokenName, var std::u32string tokenInfo) : sng2html::sng2html::Token
 66         ::= LPAREN ID!{ tokenName = lexer.GetMatch(span); } COMMA! STRINGLIT!{ tokenInfo = sng2html::sng2html::MakeStrValue(lexer.FileName(), lexer.GetToken(pos)); } RPAREN!
 67         {
 68             return sng2html::sng2html::Token(tokenName, ToUtf8(tokenInfo));
 69         }
 70         ;
 71 
 72     Keywords(var std::u32string keywordsDeclarationName, var std::unique_ptr keywords) : sng2html::sng2html::Keywords*
 73         ::= KEYWORDS ID!{ keywordsDeclarationName = lexer.GetMatch(span); } LBRACE!{ keywords.reset(new sng2html::sng2html::Keywords(keywordsDeclarationName)); }
 74             (Keyword:keyword{ keywords->Add(keyword); } % COMMA)? RBRACE!
 75         {
 76             return keywords.release();
 77         }
 78         ;
 79 
 80     Keyword(var std::u32string kw, var std::u32string tokenName) : sng2html::sng2html::Keyword*
 81         ::= LPAREN STRINGLIT!{ kw = sng2html::sng2html::MakeStrValue(lexer.FileName(), lexer.GetToken(pos)); } COMMA! ID!{ tokenName = lexer.GetMatch(span); } RPAREN!
 82         {
 83             return new sng2html::sng2html::Keyword(kw, tokenName);
 84         }
 85         ;
 86 
 87     Expressions(var int index, var std::unique_ptr expressions) : sng2html::sng2html::Expressions*
 88         ::= EXPRESSIONS{ index = 0; expressions.reset(new sng2html::sng2html::Expressions()); } LBRACE!
 89             (Expression(index):expr{ expressions->Add(expr); index = index + 1; })* RBRACE!
 90         {
 91             return expressions.release();
 92         }
 93         ;
 94 
 95     Expression(int index, var std::u32string exprName, var int line) : sng2html::sng2html::Expression*
 96         ::= ID{ exprName = lexer.GetMatch(span); } ASSIGN ExprString:exprValue!{ line = lexer.GetToken(pos).line; } SEMICOLON!
 97         {
 98             return new sng2html::sng2html::Expression(index, exprName, exprValue, line);
 99         }
100         ;
101 
102     ExprString : std::u32string
103         ::= STRINGLIT{ return sng2html::sng2html::MakeExprStringValue(lexer.FileName(), lexer.GetToken(pos)); }
104         ;
105 
106     Lexer(var std::u32string lexerDeclarationName, var std::unique_ptr currentLexer) : sng2html::sng2html::Lexer*
107         ::= LEXER Api:lexerApi ID!{ lexerDeclarationName = lexer.GetMatch(span); } LBRACE!{ currentLexer.reset(new sng2html::sng2html::Lexer(lexerApi, lexerDeclarationName)); }
108             (LexerClause(currentLexer.get()):lexerClause)* RBRACE!
109         {
110             return currentLexer.release();
111         }
112         ;
113 
114     Api(var std::u32string id) : std::u32string
115         ::= API LPAREN ID!{ id = lexer.GetMatch(span); } RPAREN!{ return id; }
116         |   empty{ return std::u32string(); }
117         ;
118 
119     LexerClause(sng2html::sng2html::Lexer* currentLexer, var int line)
120         ::= (ExprString:expr{ line = lexer.GetToken(pos).line; } Action:action CompoundStatement:stmt!){ currentLexer->AddStatement(new sng2html::sng2html::LexerStatement(expr, stmt, action, line)); }
121         |   Variables(currentLexer):variables
122         |   Actions(currentLexer):actions
123         ;
124 
125     Variables(sng2html::sng2html::Lexer* currentLexer)
126         ::= VARIABLES LBRACE! (Variable:variable{ currentLexer->AddVariable(variable); })* RBRACE!
127         ;
128 
129     Variable(var std::u32string name) : sng2html::sng2html::LexerVariable*
130         ::= TypeId:type ID{ name = lexer.GetMatch(span); } SEMICOLON{ return new sng2html::sng2html::LexerVariable(type, name); }
131         ;
132 
133     Actions(sng2html::sng2html::Lexer* currentLexer)
134         ::= ACTIONS LBRACE! ((Action:action{ pass = action != -1; } ASSIGN CompoundStatement:stmt!){ currentLexer->AddAction(new sng2html::sng2html::Action(action, stmt)); })* RBRACE!
135         ;
136 
137     Action(var int actionId) : int
138         ::= (DOLLAR LPAREN! INTLIT!{ actionId = sng2html::sng2html::MakeActionIntValue(lexer.FileName(), lexer.GetToken(pos)); } RPAREN!){ return actionId; }
139         |   empty{ return -1; }
140         ;
141 
142     ruleinfo
143     {
144         (LexerFile, "lexer file"), (Declaration, "lexer file declaration"), (ClassMap, "class map declaration"), (Prefix, "prefix declaration"), (Include, "include declaration"),
145         (Tokens, "tokens declaration"), (Token, "token declaration"), (Keywords, "keywords declaration"), (Keyword, "keyword declaration"), (Expressions, "regular expressions declaration"),
146         (Expression, "regular expression declaration"), (ExprString, "regular expression string"), (Lexer, "lexer declaration"), (Api, "API declaration"), (LexerClause, "lexer clause"),
147         (Variables, "variables"), (Variable, "variable"), (Actions, "actions"), (Action, "action identifier")
148     }
149 }