Commit | Line | Data |
---|---|---|
970ed795 | 1 | /////////////////////////////////////////////////////////////////////////////// |
3abe9331 | 2 | // Copyright (c) 2000-2015 Ericsson Telecom AB |
970ed795 EL |
3 | // All rights reserved. This program and the accompanying materials |
4 | // are made available under the terms of the Eclipse Public License v1.0 | |
5 | // which accompanies this distribution, and is available at | |
6 | // http://www.eclipse.org/legal/epl-v10.html | |
7 | /////////////////////////////////////////////////////////////////////////////// | |
8 | #ifndef _langviz_Symbol_HH | |
9 | #define _langviz_Symbol_HH | |
10 | ||
11 | #include "Node.hh" | |
12 | #include "../compiler2/string.hh" | |
13 | #include "../compiler2/vector.hh" | |
14 | #include "../compiler2/map.hh" | |
15 | ||
16 | class Symbol; | |
17 | class Grammar; | |
18 | ||
19 | /** | |
20 | * Unique set of symbols. | |
21 | */ | |
22 | class SymbolSet : public Node { | |
23 | protected: | |
24 | map<Symbol*, void> ss; | |
25 | ||
26 | SymbolSet(const SymbolSet& p); | |
27 | public: | |
28 | SymbolSet() {} | |
29 | virtual ~SymbolSet(); | |
30 | virtual SymbolSet* clone() const {return new SymbolSet(*this);} | |
31 | void add_s(Symbol *p_s); | |
32 | void add_ss(const SymbolSet& p_ss); | |
33 | void remove_s(Symbol *p_s); | |
34 | void remove_ss(const SymbolSet& p_ss); | |
35 | void remove_all(); | |
36 | size_t get_nof_ss() const {return ss.size();} | |
37 | Symbol* get_s_byIndex(size_t p_i) const {return ss.get_nth_key(p_i);} | |
38 | }; | |
39 | ||
40 | /** | |
41 | * Terminal symbols (tokens) and nonterminal symbols. | |
42 | */ | |
43 | class Symbol : public Node { | |
44 | protected: | |
45 | string id; | |
46 | string id_dot; /**< this id is used in dot file */ | |
47 | SymbolSet refd_by; /**< this symbol is referenced directly by these | |
48 | symbols */ | |
49 | SymbolSet refs; /**< these symbols are referenced directly by this | |
50 | symbol */ | |
51 | SymbolSet refd_from; /**< this symbol is referenced directly or | |
52 | indirectly from these symbols */ | |
53 | SymbolSet refs_weight; /**< these NONTERMINAL symbols are referenced | |
54 | directly or indirectly by this symbol; | |
55 | the dist of these symbols are greater | |
56 | than dist of this */ | |
57 | bool is_terminal; /**< true if is terminal symbol */ | |
58 | bool is_recursive; | |
59 | bool can_be_empty; | |
60 | int dist; /**< shortest distance from the start symbol; -1: | |
61 | unreachable */ | |
62 | int weight; /**< 1 + number of nonterminal symbols that can be | |
63 | reached from this one, and have greater dist than | |
64 | this */ | |
65 | ||
66 | Symbol(const Symbol& p); | |
67 | public: | |
68 | Symbol(const string& p_id); | |
69 | virtual ~Symbol() {} | |
70 | virtual Symbol* clone() const {return new Symbol(*this);} | |
71 | bool get_is_terminal() {return is_terminal;} | |
72 | void set_is_terminal() {is_terminal=true;} | |
73 | const string& get_id() const {return id;} | |
74 | const string& get_id_dot(); | |
75 | void add_refd_by(Symbol* p_symbol) {refd_by.add_s(p_symbol);} | |
76 | void add_refs(Symbol* p_symbol) {refs.add_s(p_symbol);} | |
77 | const SymbolSet& get_refd_by() {return refd_by;} | |
78 | const SymbolSet& get_refs() {return refs;} | |
79 | void set_is_recursive() {is_recursive=true;} | |
80 | void set_can_be_empty() {can_be_empty=true;} | |
81 | bool get_can_be_empty() {return can_be_empty;} | |
82 | void set_dist(int p_i) {if(dist==-1) dist=p_i;} | |
83 | int get_dist() {return dist;} | |
84 | int get_weight(); | |
85 | }; | |
86 | ||
87 | /** | |
88 | * Ordered list of symbols. | |
89 | */ | |
90 | class Symbols : public Node { | |
91 | protected: | |
92 | vector<Symbol> ss; /**< symbols */ | |
93 | ||
94 | Symbols(const Symbols& p); | |
95 | public: | |
96 | Symbols() {} | |
97 | virtual ~Symbols(); | |
98 | virtual Symbols* clone() const {return new Symbols(*this);} | |
99 | void add_s(Symbol *p_s); | |
100 | size_t get_nof_ss() const {return ss.size();} | |
101 | const Symbol* get_s_byIndex(size_t p_i) const {return ss[p_i];} | |
102 | Symbol*& get_s_byIndex(size_t p_i) {return ss[p_i];} | |
103 | void replace_aliases(Grammar *grammar); | |
104 | }; | |
105 | ||
106 | /** | |
107 | * Unique map of symbols. | |
108 | */ | |
109 | class SymbolMap : public Node { | |
110 | protected: | |
111 | map<string, Symbol> ss; | |
112 | ||
113 | SymbolMap(const SymbolMap& p); | |
114 | public: | |
115 | SymbolMap() {} | |
116 | virtual ~SymbolMap(); | |
117 | virtual SymbolMap* clone() const {return new SymbolMap(*this);} | |
118 | void add_s(Symbol *p_s); | |
119 | size_t get_nof_ss() const {return ss.size();} | |
120 | const Symbol* get_s_byIndex(size_t p_i) const {return ss.get_nth_elem(p_i);} | |
121 | Symbol*& get_s_byIndex(size_t p_i) {return ss.get_nth_elem(p_i);} | |
122 | bool has_s_withId(const string& p_id) const {return ss.has_key(p_id);} | |
123 | const Symbol* get_s_byId(const string& p_id) const {return ss[p_id];} | |
124 | Symbol*& get_s_byId(const string& p_id) {return ss[p_id];} | |
125 | /** Each Symbol instance is owned by the Grammar's SymbolMap. The | |
126 | * only place from where you should destruct them. */ | |
127 | void destruct_ss(); | |
128 | /** Used by Grammar after replacing aliases */ | |
129 | void destruct_symbol(const string& p_id); | |
130 | }; | |
131 | ||
132 | #endif // _langviz_Symbol_HH |