1 #include "Teuchos_Grammar.hpp" 3 #include <Teuchos_Assert.hpp> 7 #include "Teuchos_vector.hpp" 12 int get_nnonterminals(Grammar
const& g) {
13 return g.nsymbols - g.nterminals;
16 bool is_terminal(Grammar
const& g,
int symbol) {
17 TEUCHOS_DEBUG_ASSERT(0 <= symbol);
18 TEUCHOS_DEBUG_ASSERT(symbol <= g.nsymbols);
19 return symbol < g.nterminals;
22 bool is_nonterminal(Grammar
const& g,
int symbol) {
23 return !is_terminal(g, symbol);
26 int as_nonterminal(Grammar
const& g,
int symbol) {
27 return symbol - g.nterminals;
30 int find_goal_symbol(Grammar
const& g) {
31 std::set<int> nonterminals_in_rhss;
32 for (
int i = 0; i < size(g.productions); ++i) {
33 const Grammar::Production& p = at(g.productions, i);
34 for (
int j = 0; j < size(p.rhs); ++j) {
35 const int s = at(p.rhs, j);
36 TEUCHOS_DEBUG_ASSERT(0 <= s);
37 if (is_nonterminal(g, s)) nonterminals_in_rhss.insert(s);
41 for (
int s = g.nterminals; s < g.nsymbols; ++s)
42 if (!nonterminals_in_rhss.count(s)) {
44 "ERROR: there is more than one root nonterminal (" 45 << at(g.symbol_names, result) <<
" and " 46 << at(g.symbol_names, s) <<
") in this grammar\n");
50 "ERROR: the root nonterminal is unclear for this grammar\n" 51 "usually this means all nonterminals appear in the RHS of a production\n" 52 "and can be fixed by adding a new nonterminal root2, root2 -> root\n");
56 void add_end_terminal(Grammar& g) {
57 for (
int i = 0; i < size(g.productions); ++i) {
58 Grammar::Production& prod = at(g.productions, i);
59 if (is_nonterminal(g, prod.lhs)) prod.lhs++;
60 for (
int j = 0; j < size(prod.rhs); ++j) {
61 int& rhs_symb = at(prod.rhs, j);
62 if (is_nonterminal(g, rhs_symb)) rhs_symb++;
65 g.symbol_names.insert(g.symbol_names.begin() + g.nterminals,
"EOF");
70 int get_end_terminal(Grammar
const& g) {
71 return g.nterminals - 1;
74 void add_accept_production(Grammar& g) {
75 int goal_symbol = find_goal_symbol(g);
76 Grammar::Production p;
78 p.rhs.push_back(goal_symbol);
79 g.productions.push_back(p);
80 g.symbol_names.push_back(
"ACCEPT");
84 int get_accept_production(Grammar
const& g) {
85 return size(g.productions) - 1;
88 int get_accept_nonterminal(Grammar
const& g) {
89 return g.nsymbols - 1;
92 std::ostream& operator<<(std::ostream& os, Grammar
const& g) {
94 for (
int i = 0; i < size(g.symbol_names); ++i) {
95 os << i <<
": " << at(g.symbol_names, i) <<
"\n";
97 os <<
"productions:\n";
98 for (
int i = 0; i < size(g.productions); ++i) {
99 const Grammar::Production& prod = at(g.productions, i);
100 os << i <<
": " << prod.lhs <<
" ::=";
101 for (
int j = 0; j < size(prod.rhs); ++j) {
102 int symb = at(prod.rhs, j);
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
Declares Teuchos::Parser, ParserFail and make_lalr1_parser.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos, as well as a number of utility routines.