Advertisement
UnknowX

C++ Parser

Jun 20th, 2019
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.43 KB | None | 0 0
  1. #ifndef P_arser_cpp
  2. #define P_arser_cpp
  3.  
  4. #include <iostream>
  5. #include <string>
  6.  
  7. namespace command
  8. {
  9. namespace detail
  10. {
  11. inline bool is_whitespace(const char ch) {
  12. return (' ' == ch) || ('\t' == ch) ||
  13. ('\n' == ch) ;
  14. }
  15.  
  16. inline bool is_letter(const char ch) {
  17. return (('a' <= ch) && (ch <= 'z')) ||
  18. (('A' <= ch) && (ch <= 'Z')) || ('_' == ch);
  19. }
  20.  
  21. inline bool is_digit(const char ch) {
  22. return ('0' <= ch) && (ch <= '9');
  23. }
  24.  
  25. inline bool is_letter_or_digit(const char ch) {
  26. return is_letter(ch) || is_digit(ch);
  27. }
  28.  
  29. inline bool match(const char ch1, const char ch2) {
  30. return (ch1 == ch2);
  31. }
  32.  
  33. const std::string_view attributes[] =
  34. {
  35. "none_at", "color", "shape", "coords", "radio", "count", "except",
  36. };
  37.  
  38. constexpr std::size_t attributes_size = std::size(attributes);
  39.  
  40. const std::string_view commands[] =
  41. {
  42. "none_commnd", "set", "spawn", "kill"
  43. };
  44.  
  45. constexpr std::size_t commands_size = std::size(attributes);
  46. }
  47.  
  48. namespace parser
  49. {
  50. void init(), parser();
  51.  
  52. std::string command;
  53. unsigned index;
  54. }
  55.  
  56. namespace lexer
  57. {
  58. struct token
  59. {
  60.  
  61. //
  62.  
  63. static struct attribute
  64. {
  65. enum attribute_type {
  66. none_att, color, shape, coords, radio, count, except
  67. };
  68.  
  69. static attribute_type get_enum_attribute(const std::string_view str) {
  70. std::size_t index = detail::attributes_size;
  71. }
  72.  
  73. attribute() : type(none_att) {}
  74.  
  75. attribute_type type;
  76.  
  77. } enum_attribute;
  78.  
  79. //
  80.  
  81. static struct command
  82. {
  83. enum command_type {
  84. none_commnd, set, spawn, kill
  85. };
  86.  
  87. static command_type get_enum_command(std::string_view str) {
  88. std::size_t index = detail::commands_size;
  89. }
  90.  
  91. command() : type(none_commnd) {}
  92.  
  93. command_type type;
  94.  
  95. } enum_command;
  96.  
  97. //
  98.  
  99. enum token_type {
  100. none_tok, slash, c_open, brackets, c_close, ll_open, ll_close, equal, comma, colon, identifier, numeric, unknow, end
  101. };
  102.  
  103. enum value_type {
  104. none_val, integer, string,
  105.  
  106. spawn, kill, set,
  107. color, shape, coords, radio, count, except
  108. };
  109.  
  110. //
  111.  
  112. token() : tok_type(none_tok) {}
  113.  
  114. void clear()
  115. {
  116. value.clear();
  117.  
  118. tok_type = none_tok; val_type = none_val;
  119. }
  120.  
  121. token_type tok_type;
  122.  
  123. static value_type val_type;
  124. static std::string value;
  125.  
  126. } cur_token;
  127.  
  128. //
  129.  
  130. std::string token::value = {};
  131. token::value_type token::val_type = token::none_val;
  132.  
  133. token::attribute token::enum_attribute = {};
  134. token::command token::enum_command = {};
  135.  
  136. //
  137.  
  138.  
  139. token::token_type get_token()
  140. {
  141. ++parser::index;
  142.  
  143. while (detail::is_whitespace(parser::command[parser::index]))
  144. ++parser::index;
  145.  
  146. if (parser::index >= parser::command.length())
  147. {
  148. return token::end;
  149. }
  150.  
  151. switch (parser::command[parser::index])
  152. {
  153. case '/':
  154. return token::slash;
  155.  
  156. case ']':
  157. return token::c_close;
  158.  
  159. case '{':
  160. return token::ll_open;
  161.  
  162. case '}':
  163. return token::ll_close;
  164.  
  165. case ',':
  166. return token::comma;
  167.  
  168. case ':':
  169. return token::colon;
  170.  
  171. case '=':
  172. return token::equal;
  173.  
  174. case '[':
  175. if (detail::match(parser::command[++parser::index], ']'))
  176. goto label_brackets;
  177.  
  178. else
  179. {
  180. --parser::index;
  181. goto label_c_open;
  182. }
  183. break;
  184.  
  185. default:
  186. if (detail::is_letter(parser::command[parser::index]))
  187. {
  188. while (detail::is_letter_or_digit(parser::command[parser::index + 1]))
  189. {
  190. token::value += parser::command[parser::index];
  191. ++parser::index;
  192. }
  193.  
  194. token::val_type = token::string;
  195. }
  196.  
  197. else if (detail::is_digit(parser::command[parser::index]))
  198. {
  199. while (detail::is_digit(parser::command[parser::index + 1]))
  200. {
  201. token::value += parser::command[parser::index];
  202. ++parser::index;
  203. }
  204.  
  205. token::val_type = token::integer;
  206. }
  207.  
  208. token::value += parser::command[parser::index];
  209.  
  210. switch (token::val_type) {
  211. case token::string:
  212. goto label_identifier;
  213.  
  214. case token::integer:
  215. goto label_numeric;
  216. }
  217. }
  218.  
  219. return token::unknow;
  220.  
  221. label_c_open: return token::c_open;
  222. label_brackets: return token::brackets;
  223. label_numeric: return token::numeric;
  224. label_identifier: return token::identifier;
  225. }
  226.  
  227. const std::string_view to_str(const token::value_type tok) {
  228. switch (tok) {
  229. case token::none_val:
  230. return "NONE_VAL";
  231.  
  232. case token::integer:
  233. return "INTEGER";
  234.  
  235. case token::string:
  236. return "STRING";
  237.  
  238. case token::spawn:
  239. return "SPAWN";
  240.  
  241. case token::kill:
  242. return "KILL";
  243.  
  244. case token::set:
  245. return "SET";
  246.  
  247. case token::color:
  248. return "COLOR";
  249.  
  250. case token::shape:
  251. return "SHAPE";
  252.  
  253. case token::coords:
  254. return "COORDS";
  255.  
  256. case token::radio:
  257. return "RADIO";
  258.  
  259. case token::count:
  260. return "COUNT";
  261.  
  262. case token::except:
  263. return "EXCEPT";
  264. }
  265.  
  266. return "";
  267. }
  268.  
  269. const std::string_view to_str(const token::token_type tok)
  270. {
  271. switch (tok) {
  272. case token::identifier:
  273. return "IDENTIFIER";
  274.  
  275. case token::numeric:
  276. return "NUMERIC";
  277.  
  278. case token::unknow:
  279. return "UNKNOW";
  280.  
  281. case token::end:
  282. return "END";
  283.  
  284. case token::none_tok:
  285. return "NONE_TOK";
  286.  
  287. case token::slash:
  288. return "/";
  289.  
  290. case token::c_open:
  291. return "[";
  292.  
  293. case token::brackets:
  294. return "[]";
  295.  
  296. case token::c_close:
  297. return "]";
  298.  
  299. case token::ll_open:
  300. return "{";
  301.  
  302. case token::ll_close:
  303. return "}";
  304.  
  305. case token::equal:
  306. return "=";
  307.  
  308. case token::comma:
  309. return ",";
  310.  
  311. case token::colon:
  312. return ":";
  313. }
  314.  
  315. return "";
  316. }
  317.  
  318. }
  319.  
  320. namespace parser {
  321. using namespace lexer;
  322.  
  323. //
  324.  
  325. struct State {
  326. enum state_type {
  327. none_stte,
  328. };
  329.  
  330. State() : type(none_stte) {}
  331.  
  332. void clear() {
  333. type = none_stte;
  334. }
  335.  
  336. state_type type;
  337. } cur_state;
  338.  
  339. //
  340.  
  341. void init()
  342. {
  343. command.clear();
  344. index = -1;
  345.  
  346. lexer::cur_token.clear();
  347. parser::cur_state.clear();
  348. }
  349.  
  350. void parse(std::string str)
  351. {
  352. using namespace lexer;
  353.  
  354. parser::init();
  355. command = std::move(str);
  356.  
  357. while (cur_token.tok_type != token::end)
  358. {
  359. cur_token.tok_type = get_token();
  360.  
  361. }
  362. }
  363. }
  364. }
  365.  
  366. #endif //P_arser_cpp
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement