Dukales

parser to AST

Feb 18th, 2016
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.34 KB | None | 0 0
  1. #include <type_traits>
  2. #include <utility>
  3. #include <system_error>
  4. #include <sstream>
  5. #include <stdexcept>
  6. #include <regex>
  7. #include <tuple>
  8.  
  9. template< typename char_type, char_type ...chars >
  10. struct string_literal
  11. {
  12.  
  13.     static constexpr auto size = sizeof...(chars);
  14.     static constexpr char_type value[size] = {chars...};
  15.    
  16. };
  17.  
  18. template< typename char_type, char_type ...chars >
  19. constexpr const char_type string_literal< char_type, chars... >::value[size];
  20.  
  21. template< typename char_type, char_type ...chars >
  22. constexpr
  23. string_literal< char_type, chars... >
  24. operator "" _s ()
  25. {
  26.     return {};
  27. }
  28.  
  29. template< typename type >
  30. struct is_string_literal
  31.     : std::false_type
  32. {
  33.    
  34. };
  35.  
  36. template< typename char_type, char_type ...chars >
  37. struct is_string_literal< string_literal< char_type, chars... > >
  38.     : std::true_type
  39. {
  40.    
  41. };
  42.  
  43. template< typename Iterator, typename Skipper >
  44. struct parser
  45. {
  46.    
  47.     Iterator & beg;
  48.     Iterator const & end;
  49.    
  50.     Skipper skipper;
  51.  
  52.     bool success = true;
  53.    
  54.     constexpr
  55.     operator bool () const
  56.     {
  57.         return success;
  58.     }
  59.    
  60.     template< typename Attribute >
  61.     operator Attribute ();
  62.  
  63.     template< typename A, typename index_sequence = std::index_sequence<>, typename = void >
  64.     struct aggregate_arity
  65.         : index_sequence
  66.     {
  67.        
  68.     };
  69.    
  70.     template< typename A, std::size_t ...indices >
  71.     struct aggregate_arity< A, std::index_sequence< indices... >, std::__void_t< decltype(A{(indices, std::declval< parser >())..., std::declval< parser >()}) > >
  72.         : aggregate_arity< A, std::index_sequence< indices..., sizeof...(indices) > >
  73.     {
  74.        
  75.     };
  76.    
  77.     enum class category
  78.     {
  79.         unknown,
  80.        
  81.         string_literal,
  82.         arithmetic,
  83.         aggregate
  84.     };
  85.    
  86.     template< typename Attribute >
  87.     static
  88.     constexpr
  89.     bool
  90.     get_category(category const expected)
  91.     {
  92.         category category_ = category::unknown;
  93.         if (is_string_literal< Attribute >::value) {
  94.             category_ =  category::string_literal;
  95.         } else if (std::is_arithmetic< Attribute >::value) {
  96.             category_ = category::arithmetic;
  97.         } else {
  98.             category_ = category::aggregate;
  99.         }
  100.         return (category_ == expected);
  101.     }
  102.    
  103.     constexpr
  104.     void
  105.     fail()
  106.     {
  107.         success = false;
  108.     }
  109.    
  110.     constexpr
  111.     void
  112.     fail(Iterator & first)
  113.     {
  114.         beg = first;
  115.         return fail();
  116.     }
  117.    
  118.     template< typename Attribute >
  119.     constexpr
  120.     std::enable_if_t< get_category< Attribute >(category::string_literal), Attribute >
  121.     dispatch()
  122.     {
  123.         Iterator first = beg;
  124.         for (auto const & c : Attribute::value) {
  125.             if ((beg != end) && (c == *beg)) {
  126.                 ++beg;
  127.             } else {
  128.                 fail(first);
  129.                 break;
  130.             }
  131.         }
  132.         return {};
  133.     }
  134.    
  135.     template< typename Attribute >
  136.     constexpr
  137.     Attribute
  138.     dispatch(std::index_sequence<>)
  139.     {
  140.         return {*this};
  141.     }
  142.    
  143.     template< typename Attribute, std::size_t ...indices >
  144.     constexpr
  145.     Attribute
  146.     dispatch(std::index_sequence< indices... >)
  147.     {
  148.         return {(static_cast< void >(indices), *this)...};
  149.     }
  150.    
  151.     template< typename Attribute >
  152.     std::enable_if_t< get_category< Attribute >(category::aggregate), Attribute >
  153.     dispatch()
  154.     {
  155.         return dispatch< Attribute >(aggregate_arity< Attribute >{});
  156.     }
  157.    
  158.     template< typename Attribute >
  159.     std::enable_if_t< get_category< Attribute >(category::arithmetic), Attribute >
  160.     dispatch()
  161.     {
  162.         Attribute attr;
  163.         std::istringstream iss_({beg, end});
  164.         if (iss_ >> attr) {            
  165.             std::advance(beg, iss_.tellg());
  166.         } else {
  167.             fail();
  168.         }
  169.         return attr;
  170.     }
  171.    
  172. };
  173.  
  174. template< typename Iterator, typename Skipper >
  175. parser< Iterator, Skipper >
  176. parse(Iterator & beg, Iterator const & end, Skipper && skipper)
  177. {
  178.     return {beg, end, std::forward< Skipper >(skipper)};
  179. }
  180.  
  181. template< typename Iterator >
  182. auto
  183. parse(Iterator & beg, Iterator const & end)
  184. {
  185.     return parse(beg, end, std::ignore);
  186. }
  187.    
  188. template< typename Iterator, typename Skipper >
  189. template< typename Attribute >
  190. parser< Iterator, Skipper >::operator Attribute ()
  191. {
  192.     Attribute attr{};
  193.     if (operator bool ()) {
  194.         skipper = parse(beg, end);
  195.         attr = dispatch< Attribute >();
  196.     }
  197.     return attr;
  198. }
  199.  
  200. #include <iostream>
  201. #include <iterator>
  202. #include <algorithm>
  203.  
  204. #include <cstdlib>
  205.  
  206. struct ast
  207. {
  208.    
  209.     int a;
  210.     decltype("@"_s) s123;
  211.     struct
  212.     {
  213.         double x;
  214.         char c;
  215.     } s;
  216.    
  217. };
  218.  
  219. int
  220. main()
  221. {
  222.     std::string input = "0123@ 12E-1 c rest";
  223.     auto it = std::cbegin(input);
  224.     auto const end = std::cend(input);
  225.     auto skipper = " "_s;
  226.     auto parser = parse(it, end, skipper);
  227.     ast a{};
  228.     a = parser;
  229.     std::cout << a.a << ' ' << a.s.x << ' ' << a.s.c << std::endl;
  230.     if (it != end) {
  231.         std::cerr << "End of input is not reached. Rest of input:" << std::endl;
  232.         std::copy(it, end, std::ostreambuf_iterator< typename std::string::value_type >(std::cerr));
  233.         std::cerr << std::endl;
  234.     }
  235.     return EXIT_SUCCESS;
  236. }
Advertisement
Add Comment
Please, Sign In to add comment