Empirical
ConfigParser.h
Go to the documentation of this file.
1 // This file is part of Empirical, https://github.com/devosoft/Empirical
2 // Copyright (C) Michigan State University, 2016-2017.
3 // Released under the MIT Software license; see doc/LICENSE
4 //
5 // A simple parser for the Empirical configuration language.
6 //
7 // This parser is being implemented as a pushdown automata.
8 
9 #ifndef EMP_CONFIG_PARSER_H
10 #define EMP_CONFIG_PARSER_H
11 
12 #include <map>
13 #include <string>
14 
15 #include "../base/vector.h"
16 
17 #include "ConfigLexer.h"
18 
19 namespace emp {
20 
21  struct ParseRule {
22  int result_id;
24 
25  ParseRule(int id, const emp::vector<int> & _p) : result_id(id), pattern(_p) { ; }
26  };
27 
28  class ConfigParser {
29  private:
30  ConfigLexer lexer; // Lexer to provide token stream.
31  emp::vector<ParseRule> rules; // Vector of all rules linking states to productions.
32  std::map<std::string, int> state_ids; // Map of state names to their IDs.
33  int next_state; // If we add another state, what ID should we use?
34 
35  int ToStateID(const std::string & name) {
36  auto state_ptr = state_ids.find(name);
37  if (state_ptr == state_ids.end()) return next_state++;
38  return state_ptr->second;
39  }
40  int ToStateID(int state_id) const { return state_id; }
41 
42  // Take a token name or as state name and convert to its ID.
43  int StringToID(const std::string name) {
44  // @CAO Check to see if this is a TOKEN name!!!
45  return ToStateID(name);
46  }
47 
48  emp::vector<int> ToRHS(const emp::vector<std::string> & str_rhs) {
49  emp::vector<int> rhs(str_rhs.size());
50  for (int i = 0; i < (int) str_rhs.size(); i++) {
51  rhs[i] = StringToID(str_rhs[i]);
52  }
53  return rhs;
54  }
55  emp::vector<int> ToRHS(const std::string & str_rhs) {
56  return ToRHS(emp::slice(str_rhs, ' '));
57  }
58  emp::vector<int> ToRHS(const emp::vector<int> & rhs) { return rhs; }
59 
60  int AddRule_impl(int state_id, const emp::vector<int> & rhs) {
61  rules.emplace_back(state_id, rhs);
62  return state_id;
63  }
64 
65  public:
66  ConfigParser(std::istream & in_stream)
67  : lexer(in_stream), next_state(lexer.GetMaxToken()) { ; }
68  ~ConfigParser() { ; }
69 
70  // Returns state ID for rule.
71  template <typename T1, typename T2>
72  int AddRule(T1 && state, const emp::vector<int> & rhs) {
73  return AddRule_impl( ToStateID(std::forward<T1>(state)), ToRHS(std::forward<T2>(rhs)) );
74  }
75  };
76 
77 }
78 
79 #endif
int result_id
Definition: ConfigParser.h:22
ParseRule(int id, const emp::vector< int > &_p)
Definition: ConfigParser.h:25
emp::vector< int > pattern
Definition: ConfigParser.h:23
ConfigParser(std::istream &in_stream)
Definition: ConfigParser.h:66
Definition: ConfigParser.h:28
static void slice(const std::string &in_string, emp::vector< std::string > &out_set, char delim='\n')
Cut up a string based on the provided delimitor; fill them in to the provided vector.
Definition: string_utils.h:421
A rule for how parsing should work.
Definition: ConfigParser.h:21
size_t size() const
Definition: vector.h:151
void emplace_back(ARGS &&...args)
Definition: vector.h:219
~ConfigParser()
Definition: ConfigParser.h:68
If we are in emscripten, make sure to include the header.
Definition: array.h:37
Definition: ConfigLexer.h:24
int AddRule(T1 &&state, const emp::vector< int > &rhs)
Definition: ConfigParser.h:72