File: ParserDriver.hpp

package info (click to toggle)
fauhdlc 20180504-2
  • links: PTS
  • area: main
  • in suites: buster
  • size: 2,956 kB
  • sloc: cpp: 23,188; ansic: 6,077; yacc: 3,764; lex: 763; makefile: 605; sh: 494; xml: 403
file content (317 lines) | stat: -rw-r--r-- 9,523 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
/* $Id$ 
 *
 * ParserDriver: glue class to driver between scanner and parser.
 *
 * Copyright (C) 2007-2009 FAUmachine Team <info@faumachine.org>.
 * This program is free software. You can redistribute it and/or modify it
 * under the terms of the GNU General Public License, either version 2 of
 * the License, or (at your option) any later version. See COPYING.
 */

#ifndef __PARSER_DRIVER_HPP_INCLUDED
#define __PARSER_DRIVER_HPP_INCLUDED

/* attention, this file get's included in several nasty places:
   1) at the beginning of the generated scanner. Thus some glue 
      definitions to make it work.
   2) From the code-file of the parser
*/

#include <string>
#include <stdexcept>
#include <stack>
#include "FAUhdlParser.tab.hh"
#include "location.hh"
#include "frontend/ast/LibraryList.hpp"
#include "frontend/ast/Location.hpp"
#include "frontend/reporting/SyntaxError.hpp"
#include "frontend/misc/SymbolTable.hpp"
#include "frontend/misc/NameLookup.hpp"
#include "frontend/reporting/SyntaxError.hpp"
#include "frontend/reporting/CompileError.hpp"

namespace yy {
	class ParserDriver;
	class Identifier;
};

/* Announce to Flex the prototype we want for lexing function, ... */
#define YY_DECL								\
  yy::FAUhdlParser::token_type						\
  yy::FAUhdlScanner::yylex(yy::FAUhdlParser::semantic_type* yylval,	\
        yy::FAUhdlParser::location_type* yylloc,			\
        ParserDriver& driver)

/* redefine yyterminate, to be of the same type */
#define yyterminate() return token::t_EOF

namespace ast {
	class Symbol;
};

namespace yy {

class FAUhdlScanner;


/** Glue class, that connects the scanner and the parser.
 */
class ParserDriver {
public:
	/** c'tor 
	 *  @param symTab symbol table instance for the scanner. */
	ParserDriver(ast::SymbolTable& symTab);

	/** d'tor */
	virtual ~ParserDriver();

	/** glue function that will call the real flexer
         *  @param yylval Semantic value of scanned token.
         *  @param yylloc Location of scanned token.
         */
	int 
	yylex(
		yy::FAUhdlParser::semantic_type* yylval,
		yy::FAUhdlParser::location_type* yylloc
	);

	//! Report a parse error.
        /** Used as callback from the parser.
         *  @param l Location of parse errror.
         *  @param msg error message.
         */
	void 
	error(
		const yy::FAUhdlParser::location_type& l,
		const std::string& msg
	) /* throw(SyntaxError) */;

	/** Parse a file.
	 *  @exception runtime_error in case the file could not get opened.
	 *  @exception SyntaxError in case there were errors during parsing.
	 *  @param filename name of file
	 *  @param lib library name the file is in.
	 */
	void parse(
		const std::string& filename,
		const char *lib
		)	/* throw(std::runtime_error, SyntaxError, 
				ast::CompileError) */;

	//! Convert a string to lower case.
        /** The argument will get overwritten with the result.
         *  @param mixed convert this string to lower case
         */
	static void 
	toLower(std::string& mixed);

	//! Make an float/int from a vhdl based real/int literal.
	/** can be instantiated with any number type, that can be 
          * static_cast from long.
	  * @param number based vhdl float/int, e.g. 16#FF.1A#E+1
	  * @return value of the double
	  * @exception std::invalid_argument in case no base specifier
	  *            is present.
	  */
	template <typename T>
	static T 
	makeBased(std::string number) /* throw(std::invalid_argument) */;

	//! Make an float/int from a vhdl unbased real literal.
	/** can be instantiated with any number type, that can be 
          * static_cast from long.
	  * @param number vhdl float/int, e.g. 123.456E-14
	  * @return value of the double
	  */
	template <typename T>
	static T 
	makeBase10(std::string number);

	//! Remove double quotes from a string.
	/** will turn "" to ", and also remove the surrounding quotes.
	 *  @param s string to mangle.
	 *  @return correct string, caller needs to free the allocated mem.
	 */
	static std::string* 
	removeQuotes(std::string s);

	//! Normalize a vhdl bit string.
	/** Remove surrounding quotes and normalize to binary values.
	 *  @param s string that will get normalized.
	 *  @return normalized bit string.
	 *  @exception if the digit is bigger than allowed.
	 */
	static std::string* 
	makeBitString(std::string s) /* throw(std::out_of_range) */;

	//! build an ast::Location.
	/** build an ast::Location with the given yy::location and the current
          * file as filename.
          *
          * @param loc location in the parser.
          * @return Location with linenumber and filename.
          */
	ast::Location
	bl(const location& loc) const {
		return ast::Location(loc.begin.line, this->currentFile);
	}

	//! register given unit to current library.
	/** register the Library unit unit to the currently opened libary.
	 *  @param unit to register
	 */
	void registerLibUnit(ast::LibUnit *unit);

	//! lookup a symbol in the SymbolTable and return the according token.
	/** wrapper to coordinate between SymbolTable and Scanner.
	 *  @param id string of the identifier
	 *  @param semanticValue semantic value that will get filled in.
	 *  @param loc location of the identifier
	 *  @return identifier token type.
	 */
	FAUhdlParser::token_type 
	getTokenForId(
		const char *id, 
		ast::NodeFactory::Identifier *&semanticValue,
		const FAUhdlParser::location_type &loc) const;

	//! build the SimpleName of an operator.
	/** Build the SimpleName of an operator, look it up in the 
	 *  SymbolTable and complain, if no candidates are found.
	 *
	 *  @param op name of the operator.
	 *  @param loc location of the operator symbol
	 *  @return created SimpleName.
	 */
	ast::SimpleName*
	buildOperatorName(
		const char *op, 
		const FAUhdlParser::location_type &loc) const;

	//! register all symbols in symbols with type
	/** register all symbols named in symbols into the current
	 *  region of the symbolTable.
	 *  
	 *  @param symbols list of symbols to register.
	 *  @param type type to register symbols.
	 */
	template <typename T>
	void registerSymbolDecls(
		const T *symbols,
		enum ast::symType type
		);

	/** scanner instance */
	FAUhdlScanner *scanner;
	
	/** top DesignUnitList */
	ast::LibraryList *topNode;

	/** current library */
	ast::Library *currentLibrary;

	/** symboltable instance for scanner */
	ast::SymbolTable &symbolTable;

	/** glue frontend for SymbolTable while parsing */
	ast::NameLookup &nameLookup;

	/** should identifiers get looked up and reported as individual 
	 *  ID_* instances?
	 */
	bool lookupIdentifiers;

	/** current label (or NULL) for the sequential/concurrent statement */
	std::string *label;

	/** top will point to the current callable, so that a return statement
	 *  can lookup to which it applies.
	 *  If empty (i.e. outside of a subprogram), no return statement is 
	 *  allowed.
	 */
	std::stack<ast::Callable*> subprogStack;

private:
	//! Convert an integer string to a long int.
	/** @param intval sequence of characteres [0-9a-zA-Z], with an 
         *         optional prefix of + or -.
         *  @param base base multiplier.
         *  @return value of intval.
         *  @exception invalid_argument intval contains other characters
         *  @exception out_of_range intval characters have greater value
         *	        than base
         */
	static long 
	makeLong(const std::string& intval, unsigned char base)
		/* throw(std::invalid_argument, std::out_of_range) */;

	//! Determine the value of a ascii (extended) digit.
	/** @param c ascii digit.
	 *  @return value of the digit or -1 if out of range.
	 */
	static int
	getDigitValue(char c);

	//! Normalize a hex bit string.
	/** @return normalized bit string. Caller must free it.
	 *  @param s vhdl hex bit string
	 */
	static std::string* 
	makeHexBitString(std::string& s);
	
	//! Normalize a octal bit string.
	/** @return normalized string. Caller must free it.
	 *  @param s vhdl octal bit string.
	 *  @exception std::out_of_range if a digit is not an octal
	 *                  digit.
	 */
	static std::string* 
	makeOctBitString(std::string& s) /* throw(std::out_of_range) */;

	//! Convert sting number to T.
	/** @param val value of actual number +-[0-9a-zA-Z] optional with .
         *  @param exponent value of exponent (base 10): [eE]?[+-]?[0-9]*
         *  @param base base multiplier.
         *  @return value of number.
         *
         *  Note: val and exponent may get modified.
         */
	template <typename T>
	static T 
	makeNumberFromParts(
		std::string& val,
		std::string& exponent,
		unsigned char base
	);

	//! reduce candidates to the correct token type.
	/** reduce the list of candidate symbols candidates to the
	 *  corresponding token type for the parser.
	 *  @param candidates list of symbol candidates.
	 *  @return corresponding token type for candidates.
	 */
	static FAUhdlParser::token_type
	reduceSymbolToToken(std::list<ast::Symbol*> candidates);

	//! report that id could not have been found.
	/** report an error that the identifier id could not get looked up.
	 *  @param id identifier without symbol.
	 *  @param loc corresponding location
	 */
	void reportNameError(
		const char *id, 
		const FAUhdlParser::location_type &loc) const;

	/** name of the current file */
	const std::string* currentFile;

	/** current location of scanner. */
	FAUhdlParser::location_type *currentLoc;
}; /* class declaration */

}; /* namespace yy */

/* include template definition */
#include "ParserDriver.tpp"

#endif /* __PARSER_DRIVER_HPP_INCLUDED */