blob: f55ab396f4b56edf54a30d6b44e043d6dbc5b8ac [file] [log] [blame]
Václav Kubernát8cd63422018-03-19 17:10:13 +01001/*
2 * Copyright (C) 2018 CESNET, https://photonics.cesnet.cz/
Václav Kubernátd6662962018-03-22 17:41:33 +01003 * Copyright (C) 2018 FIT CVUT, https://fit.cvut.cz/
Václav Kubernát8cd63422018-03-19 17:10:13 +01004 *
5 * Written by Václav Kubernát <kubervac@fit.cvut.cz>
6 *
7*/
8#pragma once
9#include <boost/spirit/home/x3.hpp>
Václav Kubernát8cd63422018-03-19 17:10:13 +010010#include <boost/spirit/home/x3/support/ast/position_tagged.hpp>
Václav Kubernátd6662962018-03-22 17:41:33 +010011
Václav Kubernát8cd63422018-03-19 17:10:13 +010012#include <boost/fusion/adapted/struct/adapt_struct.hpp>
13#include <boost/fusion/include/adapt_struct.hpp>
Václav Kubernátd6662962018-03-22 17:41:33 +010014#include <vector>
15
Václav Kubernát8cd63422018-03-19 17:10:13 +010016#include "CTree.hpp"
17namespace x3 = boost::spirit::x3;
18namespace ascii = boost::spirit::x3::ascii;
19
20using x3::alpha;
21using x3::alnum;
22using x3::lit;
23using x3::char_;
24using x3::_attr;
25using x3::lexeme;
26using ascii::space;
27
Václav Kubernátd6662962018-03-22 17:41:33 +010028struct ParserContext {
Václav Kubernát8cd63422018-03-19 17:10:13 +010029 ParserContext(const CTree& tree);
30 const CTree& m_tree;
Václav Kubernátd6662962018-03-22 17:41:33 +010031 std::string m_curPath;
Václav Kubernát8cd63422018-03-19 17:10:13 +010032};
33
34struct parser_context_tag;
35
Václav Kubernátd6662962018-03-22 17:41:33 +010036struct container_ {
37 container_() {}
38 container_(const std::string& name);
39
40 bool operator==(const container_& b) const;
41
42 char m_first = ' ';
Václav Kubernát8cd63422018-03-19 17:10:13 +010043 std::string m_name;
44};
45
46BOOST_FUSION_ADAPT_STRUCT(container_, m_first, m_name)
47
Václav Kubernátd6662962018-03-22 17:41:33 +010048struct path_ {
49 bool operator==(const path_& b) const;
Václav Kubernát8cd63422018-03-19 17:10:13 +010050 std::vector<container_> m_nodes;
51};
52
53BOOST_FUSION_ADAPT_STRUCT(path_, m_nodes)
54
Václav Kubernátd6662962018-03-22 17:41:33 +010055struct cd_ {
56 bool operator==(const cd_& b) const;
Václav Kubernát8cd63422018-03-19 17:10:13 +010057 path_ m_path;
58};
59
60BOOST_FUSION_ADAPT_STRUCT(cd_, m_path)
61
62
Václav Kubernátd6662962018-03-22 17:41:33 +010063struct container_class {
Václav Kubernát8cd63422018-03-19 17:10:13 +010064 template <typename T, typename Iterator, typename Context>
Václav Kubernátd6662962018-03-22 17:41:33 +010065 void on_success(Iterator const&, Iterator const&, T& ast, Context const& context)
66 {
67 ast.m_name = ast.m_first + ast.m_name;
68 auto& parserContext = x3::get<parser_context_tag>(context);
69 const auto& tree = parserContext.m_tree;
70
71 if (tree.isContainer(parserContext.m_curPath, ast.m_name)) {
72 if (!parserContext.m_curPath.empty()) {
73 parserContext.m_curPath += '/';
74 }
75 parserContext.m_curPath += ast.m_name;
76 } else {
77 throw InvalidNodeException("No container with the name \"" + ast.m_name + "\" in \"" + parserContext.m_curPath + "\"");
78 }
79 }
Václav Kubernát8cd63422018-03-19 17:10:13 +010080};
81
Václav Kubernátd6662962018-03-22 17:41:33 +010082struct path_class {
Václav Kubernát8cd63422018-03-19 17:10:13 +010083 template <typename T, typename Iterator, typename Context>
Václav Kubernátd6662962018-03-22 17:41:33 +010084 void on_success(Iterator const&, Iterator const&, T&, Context const&)
85 {
86 }
Václav Kubernát8cd63422018-03-19 17:10:13 +010087};
88
Václav Kubernátd6662962018-03-22 17:41:33 +010089struct cd_class {
Václav Kubernát8cd63422018-03-19 17:10:13 +010090 template <typename T, typename Iterator, typename Context>
Václav Kubernátd6662962018-03-22 17:41:33 +010091 void on_success(Iterator const&, Iterator const&, T&, Context const&)
92 {
93 }
Václav Kubernát8cd63422018-03-19 17:10:13 +010094};
95
96
Václav Kubernátd6662962018-03-22 17:41:33 +010097x3::rule<container_class, container_> const container = "container";
98x3::rule<path_class, path_> const path = "path";
99x3::rule<cd_class, cd_> const cd = "cd";
Václav Kubernát8cd63422018-03-19 17:10:13 +0100100
Václav Kubernát8cd63422018-03-19 17:10:13 +0100101
Václav Kubernátd6662962018-03-22 17:41:33 +0100102auto const identifier =
103 lexeme[
104 ((alpha | char_("_")) >> *(alnum | char_("_") | char_("-") | char_(".")))
105 ];
Václav Kubernát8cd63422018-03-19 17:10:13 +0100106
107auto const container_def =
Václav Kubernátd6662962018-03-22 17:41:33 +0100108 identifier;
109
Václav Kubernát8cd63422018-03-19 17:10:13 +0100110auto const path_def =
111 container % '/';
112
113auto const cd_def =
114 lit("cd") >> path >> x3::eoi;
115
116BOOST_SPIRIT_DEFINE(container)
117BOOST_SPIRIT_DEFINE(path)
118BOOST_SPIRIT_DEFINE(cd)