Click
Loading...
Searching...
No Matches
lexer.hh
1// -*- c-basic-offset: 4; related-file-name: "../../lib/lexer.cc" -*-
2#ifndef CLICK_LEXER_HH
3#define CLICK_LEXER_HH
4#include <click/hashtable.hh>
5#include <click/router.hh>
6#include <click/glue.hh>
7#include <click/variableenv.hh>
8CLICK_DECLS
9class LexerExtra;
10
11enum Lexemes {
12 lexEOF = 0,
13 lexIdent = 256, // see also Lexer::lexeme_string
14 lexVariable,
15 lexArrow,
16 lex2Arrow,
17 lexContextArrow,
18 lex2Colon,
19 lex2Bar,
20 lex3Dot,
21 lexElementclass,
22 lexRequire,
23 lexProvide,
24 lexDefine
25};
26
27class Lexeme { public:
28
29 Lexeme()
30 : _kind(lexEOF) {
31 }
32 Lexeme(int k, const String &s, bool compact = false)
33 : _kind(k), _s(compact ? s.compact() : s) {
34 }
35
36 int kind() const { return _kind; }
37 bool is(int k) const { return _kind == k; }
38
39 const String &string() const { return _s; }
40 String &string() { return _s; }
41
42 private:
43
44 int _kind;
45 String _s;
46
47};
48
49class Lexer { public:
50
51 enum { TUNNEL_TYPE = 0, ERROR_TYPE = 1 };
52
53 class TunnelEnd;
54 class Compound;
55 typedef Router::Port Port;
56 typedef Router::Connection Connection;
57
58 Lexer();
59 virtual ~Lexer();
60
61 static Lexer* get_lexer();
62 static bool lexer_initialized();
63 static void static_cleanup();
64
65 int begin_parse(const String &data, const String &filename, LexerExtra *, ErrorHandler * = 0);
66 void end_parse(int);
67
68 VariableEnvironment &global_scope() { return _global_scope; }
69 ErrorHandler *errh() const { return _errh; }
70
71 String remaining_text() const;
72 void set_remaining_text(const String &);
73
74 Lexeme lex() {
75 return _unlex_pos ? _unlex[--_unlex_pos] : next_lexeme();
76 }
77 void unlex(const Lexeme &t) {
78 assert(_unlex_pos < UNLEX_SIZE);
79 _unlex[_unlex_pos++] = t;
80 }
81 String lex_config() {
82 assert(!_unlex_pos);
83 return _file.lex_config(this);
84 }
85
86 bool expect(int, bool no_error = false);
87
88 typedef Element *(*ElementFactory)(uintptr_t);
89#ifdef CLICK_LINUXMODULE
90 int add_element_type(const String &, ElementFactory factory, uintptr_t thunk, struct module *module, bool scoped = false);
91#else
92 int add_element_type(const String &, ElementFactory factory, uintptr_t thunk, bool scoped = false);
93#endif
94 void add_element_mtsafe(const String &);
95
96 int element_type(const String &name) const {
97 return _element_type_map[name];
98 }
99 int force_element_type(String name, bool report_error = true);
100
101 void element_type_names(Vector<String> &) const;
102
103 int remove_element_type(int t) { return remove_element_type(t, 0); }
104
105 bool is_mt_safe(String element) const;
106
107 String element_name(int) const;
108 String element_landmark(int) const;
109
110 void add_tunnels(String name, int *eidexes);
111
112 bool ydone() const { return !_ps; }
113 void ystep();
114
115 Router *create_router(Master *);
116
117 private:
118
119 enum {
120 max_depth = 50
121 };
122
123 struct FileState {
124 String _big_string;
125 const char *_end;
126 const char *_pos;
127 String _filename;
128 String _original_filename;
129 unsigned _lineno;
130
131 FileState(const String &data, const String &filename);
132 const char *skip_line(const char *s);
133 const char *skip_slash_star(const char *s);
134 const char *skip_backslash_angle(const char *s);
135 const char *skip_quote(const char *s, char end_c);
136 const char *process_line_directive(const char *s, Lexer *lexer);
137 Lexeme next_lexeme(Lexer *lexer);
138 String lex_config(Lexer *lexer);
139 String landmark() const;
140 };
141
142 struct ElementState;
143 struct ParseState;
144
145 // lexer
146 FileState _file;
147 bool _compact_config;
148 LexerExtra *_lextra;
149
150 Lexeme next_lexeme() {
151 return _file.next_lexeme(this);
152 }
153 static String lexeme_string(int);
154
155 // parser
156 enum { UNLEX_SIZE = 2 };
157 Lexeme _unlex[2];
158 int _unlex_pos;
159
160 // element types
161 struct ElementType {
162 ElementFactory factory;
163 uintptr_t thunk;
164#ifdef CLICK_LINUXMODULE
165 struct module *module;
166#endif
167 String name;
168 int next;
169
170 inline Compound* compound() const {
171 if (factory == compound_element_factory)
172 return reinterpret_cast<Compound*>(thunk);
173 else
174 return 0;
175 }
176 };
177 HashTable<String, int> _element_type_map;
178 HashTable<String, bool> _element_mtsafe_map;
179 Vector<ElementType> _element_types;
180 enum { ET_SCOPED = 0x80000000, ET_TMASK = 0x7FFFFFFF, ET_NULL = 0x7FFFFFFF };
181 int _last_element_type;
182 int _free_element_type;
183 VariableEnvironment _global_scope;
184
185 // elements
186 Compound *_c;
187 ParseState *_ps;
188 int _group_depth;
189
190 Vector<TunnelEnd *> _tunnels;
191
192 // compound elements
193 int _anonymous_offset;
194
195 // requirements
196 Vector<String> _requirements;
197 Vector<String> _libraries;
198
199 // errors
200 ErrorHandler *_errh;
201
202 // global lexer
203 static Lexer* _lexer;
204
205 int lerror(const char *, ...);
206 int lerror_syntax(const Lexeme &t);
207
208 String anon_element_name(const String &) const;
209 int get_element(String name, int etype,
210 const String &configuration = String(),
211 const String &filename = String(), unsigned lineno = 0);
212 int lexical_scoping_in() const;
213 void lexical_scoping_out(int);
214 int remove_element_type(int, int *);
215 int make_compound_element(int);
216 void expand_compound_element(int, VariableEnvironment &);
217 void add_router_connections(int, const Vector<int> &);
218 static Element* compound_element_factory(uintptr_t);
219
220 void yport(bool isoutput);
221 void yelement_name();
222 void yelement_type(int type, bool this_ident, bool this_implicit);
223 void yelement_config(ElementState *e, bool this_implicit);
224 void yelement_next();
225
226 void yconnection_connector();
227 void yconnection_check_useless(const Vector<int> &x, bool isoutput);
228 static void yconnection_analyze_ports(const Vector<int> &x, bool isoutput,
229 int &min_ports, int &expandable);
230 void yconnection_connect_all(Vector<int> &outputs, Vector<int> &inputs, int connector, String context);
231
232 void ycompound_arguments(Compound *ct);
233 void ycompound();
234 void ycompound_next();
235 void ycompound_end(const Lexeme &t);
236 void ygroup();
237 void ygroup_end();
238
239 void yelementclass();
240 void yrequire();
241 void yrequire_library(const String &value);
242 void yvar();
243
244 void ystatement();
245
246 TunnelEnd *find_tunnel(const Port &p, bool isoutput, bool insert);
247 void expand_connection(const Port &p, bool isoutput, Vector<Port> &);
248
249 friend class Compound;
250 friend class TunnelEnd;
251 friend struct FileState;
252
253};
254
255class LexerExtra { public:
256
257 LexerExtra() { }
258 virtual ~LexerExtra() { }
259
260 virtual void require(String type, String value, ErrorHandler *errh);
261
262};
263
264CLICK_ENDDECLS
265#endif
Base class for Click elements.
Definition element.hh:42
Error reporting class.
Definition error.hh:90
Hash table template.
Definition hashtable.hh:570
A router configuration.
Definition router.hh:28
A string of characters.
Definition string.hh:22
Vector template.
Definition vector.hh:111
Click's hash table container template.
The Router class implementing a router configuration.