Teuchos - Trilinos Tools Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Teuchos_Parser.cpp
1 // @HEADER
2 // *****************************************************************************
3 // Teuchos: Common Tools Package
4 //
5 // Copyright 2004 NTESS and the Teuchos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #include "Teuchos_Parser.hpp"
11 
12 #include "Teuchos_Table.hpp"
13 #include "Teuchos_make_lalr1_parser.hpp"
14 
15 namespace Teuchos {
16 
17 template struct Table<Action>;
18 
19 Parser::Parser(GrammarPtr g, int nstates_reserve):
20  grammar(g),
21  terminal_table(g->nterminals, nstates_reserve),
22  nonterminal_table(get_nnonterminals(*g), nstates_reserve) {
23 }
24 
25 int get_nstates(Parser const& p) {
26  return get_nrows(p.terminal_table);
27 }
28 
29 int add_state(Parser& p) {
30  int state = get_nstates(p);
31  resize(p.terminal_table, state + 1, get_ncols(p.terminal_table));
32  resize(p.nonterminal_table, state + 1, get_ncols(p.nonterminal_table));
33  for (int t = 0; t < p.grammar->nterminals; ++t) {
34  Action action;
35  action.kind = ACTION_NONE;
36  at(p.terminal_table, state, t) = action;
37  }
38  for (int nt = 0; nt < get_nnonterminals(*(p.grammar)); ++nt) {
39  at(p.nonterminal_table, state, nt) = -1;
40  }
41  return state;
42 }
43 
44 void add_terminal_action(Parser& p, int state, int terminal, Action action) {
45  TEUCHOS_ASSERT(at(p.terminal_table, state, terminal).kind == ACTION_NONE);
46  TEUCHOS_ASSERT(action.kind != ACTION_NONE);
47  if (action.kind == ACTION_SHIFT) {
48  TEUCHOS_ASSERT(0 <= action.next_state);
49  TEUCHOS_ASSERT(action.next_state < get_nstates(p));
50  } else {
51  TEUCHOS_ASSERT(0 <= action.production);
52  TEUCHOS_ASSERT(action.production < Teuchos::size(p.grammar->productions));
53  }
54  at(p.terminal_table, state, terminal) = action;
55 }
56 
57 void add_nonterminal_action(Parser& p, int state, int nonterminal, int next_state) {
58  TEUCHOS_ASSERT(0 <= next_state);
59  TEUCHOS_ASSERT(next_state < get_nstates(p));
60  TEUCHOS_ASSERT(at(p.nonterminal_table, state, nonterminal) == -1);
61  at(p.nonterminal_table, state, nonterminal) = next_state;
62 }
63 
64 Action const& get_action(Parser const& p, int state, int terminal) {
65  return at(p.terminal_table, state, terminal);
66 }
67 
68 int execute_action(Parser const& p, std::vector<int>& stack, Action const& action) {
69  TEUCHOS_ASSERT(action.kind != ACTION_NONE);
70  if (action.kind == ACTION_SHIFT) {
71  stack.push_back(action.next_state);
72  } else {
73  const Grammar::Production& prod = at(p.grammar->productions, action.production);
74  for (int i = 0; i < Teuchos::size(prod.rhs); ++i) stack.pop_back();
75  TEUCHOS_ASSERT(p.grammar.get());
76  const Grammar& grammar = *(p.grammar);
77  int nt = as_nonterminal(grammar, prod.lhs);
78  TEUCHOS_ASSERT(!stack.empty());
79  int next_state = at(p.nonterminal_table, stack.back(), nt);
80  stack.push_back(next_state);
81  }
82  return stack.back();
83 }
84 
85 GrammarPtr const& get_grammar(Parser const& p) { return p.grammar; }
86 
87 ParserFail::ParserFail(const std::string& msg):
88  std::invalid_argument(msg) {
89 }
90 
91 } // end namespace Teuchos
Declares Teuchos::Parser, ParserFail and make_lalr1_parser.
#define TEUCHOS_ASSERT(assertion_test)
This macro is throws when an assert fails.