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 */
|