2012-04-13 01:08:20 +00:00
|
|
|
|
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
2006-08-26 11:35:28 +00:00
|
|
|
|
//*************************************************************************
|
|
|
|
|
// DESCRIPTION: Verilog::Preproc: Internal header for lex interfacing
|
|
|
|
|
//
|
2008-04-25 12:14:27 +00:00
|
|
|
|
// Code available from: http://www.veripool.org/verilator
|
2006-08-26 11:35:28 +00:00
|
|
|
|
//
|
|
|
|
|
//*************************************************************************
|
|
|
|
|
//
|
2017-01-15 17:09:59 +00:00
|
|
|
|
// Copyright 2000-2017 by Wilson Snyder. This program is free software;
|
2010-02-07 11:40:48 +00:00
|
|
|
|
// you can redistribute it and/or modify it under the terms of either the
|
|
|
|
|
// GNU Lesser General Public License Version 3 or the Perl Artistic License
|
|
|
|
|
// Version 2.0.
|
2006-08-26 11:35:28 +00:00
|
|
|
|
//
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
|
//
|
|
|
|
|
//*************************************************************************
|
|
|
|
|
// This header provides the interface between the lex proper V3PreLex.l/.cpp
|
|
|
|
|
// and the class implementation file V3Pre.cpp
|
|
|
|
|
// It is not intended for user applications.
|
|
|
|
|
//*************************************************************************
|
|
|
|
|
|
|
|
|
|
#ifndef _VPREPROCLEX_H_ // Guard
|
|
|
|
|
#define _VPREPROCLEX_H_ 1
|
|
|
|
|
|
2010-04-07 00:20:44 +00:00
|
|
|
|
#include <deque>
|
2009-09-18 02:23:18 +00:00
|
|
|
|
#include <stack>
|
|
|
|
|
|
2006-08-26 11:35:28 +00:00
|
|
|
|
#include "V3Error.h"
|
2014-11-22 16:48:39 +00:00
|
|
|
|
#include "V3FileLine.h"
|
2006-08-26 11:35:28 +00:00
|
|
|
|
|
2010-07-09 00:31:41 +00:00
|
|
|
|
//======================================================================
|
|
|
|
|
|
2012-02-24 02:37:49 +00:00
|
|
|
|
class V3PreLex;
|
2010-07-09 00:31:41 +00:00
|
|
|
|
class V3PreProcImp;
|
|
|
|
|
|
2006-08-26 11:35:28 +00:00
|
|
|
|
// Token codes
|
2010-07-09 00:31:41 +00:00
|
|
|
|
// If changing, see V3PreProc.cpp's V3PreProcImp::tokenName()
|
2006-08-26 11:35:28 +00:00
|
|
|
|
#define VP_EOF 0
|
|
|
|
|
|
|
|
|
|
#define VP_INCLUDE 256
|
|
|
|
|
#define VP_IFDEF 257
|
|
|
|
|
#define VP_IFNDEF 258
|
|
|
|
|
#define VP_ENDIF 259
|
|
|
|
|
#define VP_UNDEF 260
|
|
|
|
|
#define VP_DEFINE 261
|
|
|
|
|
#define VP_ELSE 262
|
|
|
|
|
#define VP_ELSIF 263
|
2007-06-13 17:34:09 +00:00
|
|
|
|
#define VP_LINE 264
|
2009-12-21 03:26:48 +00:00
|
|
|
|
#define VP_UNDEFINEALL 265
|
2006-08-26 11:35:28 +00:00
|
|
|
|
|
|
|
|
|
#define VP_SYMBOL 300
|
|
|
|
|
#define VP_STRING 301
|
|
|
|
|
#define VP_DEFVALUE 302
|
|
|
|
|
#define VP_COMMENT 303
|
|
|
|
|
#define VP_TEXT 304
|
|
|
|
|
#define VP_WHITE 305
|
|
|
|
|
#define VP_DEFREF 306
|
|
|
|
|
#define VP_DEFARG 307
|
|
|
|
|
#define VP_ERROR 308
|
2009-05-11 15:57:43 +00:00
|
|
|
|
#define VP_DEFFORM 309
|
2010-07-10 22:30:16 +00:00
|
|
|
|
#define VP_STRIFY 310
|
|
|
|
|
#define VP_BACKQUOTE 311
|
2010-09-20 19:20:16 +00:00
|
|
|
|
#define VP_SYMBOL_JOIN 312
|
|
|
|
|
#define VP_DEFREF_JOIN 313
|
2017-10-10 22:44:10 +00:00
|
|
|
|
#define VP_JOIN 314
|
2009-05-11 15:57:43 +00:00
|
|
|
|
|
|
|
|
|
#define VP_PSL 350
|
2006-08-26 11:35:28 +00:00
|
|
|
|
|
|
|
|
|
//======================================================================
|
|
|
|
|
// Externs created by flex
|
|
|
|
|
// We add a prefix so that other lexers/flexers in the same program won't collide.
|
|
|
|
|
#ifndef yy_create_buffer
|
|
|
|
|
# define yy_create_buffer V3PreLex_create_buffer
|
|
|
|
|
# define yy_delete_buffer V3PreLex_delete_buffer
|
|
|
|
|
# define yy_scan_buffer V3PreLex_scan_buffer
|
|
|
|
|
# define yy_scan_string V3PreLex_scan_string
|
|
|
|
|
# define yy_scan_bytes V3PreLex_scan_bytes
|
|
|
|
|
# define yy_flex_debug V3PreLex_flex_debug
|
|
|
|
|
# define yy_init_buffer V3PreLex_init_buffer
|
|
|
|
|
# define yy_flush_buffer V3PreLex_flush_buffer
|
|
|
|
|
# define yy_load_buffer_state V3PreLex_load_buffer_state
|
|
|
|
|
# define yy_switch_to_buffer V3PreLex_switch_to_buffer
|
|
|
|
|
# define yyin V3PreLexin
|
|
|
|
|
# define yyleng V3PreLexleng
|
|
|
|
|
# define yylex V3PreLexlex
|
|
|
|
|
# define yyout V3PreLexout
|
|
|
|
|
# define yyrestart V3PreLexrestart
|
|
|
|
|
# define yytext V3PreLextext
|
|
|
|
|
# define yyerror V3PreLexerror
|
|
|
|
|
# define yyerrorf V3PreLexerrorf
|
|
|
|
|
#endif
|
|
|
|
|
|
2010-03-05 17:02:56 +00:00
|
|
|
|
#ifndef yyourleng
|
|
|
|
|
# define yyourleng V3PreLexourleng
|
|
|
|
|
# define yyourtext V3PreLexourtext
|
|
|
|
|
#endif
|
|
|
|
|
|
2006-08-26 11:35:28 +00:00
|
|
|
|
#ifndef YY_BUFFER_STATE
|
|
|
|
|
struct yy_buffer_state;
|
|
|
|
|
typedef struct yy_buffer_state *YY_BUFFER_STATE;
|
|
|
|
|
# define YY_BUF_SIZE 16384
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
extern int yylex();
|
|
|
|
|
extern void yyrestart(FILE*);
|
2010-03-05 17:02:56 +00:00
|
|
|
|
|
|
|
|
|
// Accessors, because flex keeps changing the type of yyleng
|
|
|
|
|
extern char* yyourtext();
|
|
|
|
|
extern size_t yyourleng();
|
|
|
|
|
extern void yyourtext(const char* textp, size_t size); // Must call with static
|
2010-02-27 00:50:44 +00:00
|
|
|
|
|
2006-08-26 11:35:28 +00:00
|
|
|
|
YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size );
|
|
|
|
|
void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer );
|
|
|
|
|
void yy_delete_buffer( YY_BUFFER_STATE b );
|
|
|
|
|
|
|
|
|
|
//======================================================================
|
|
|
|
|
|
|
|
|
|
#define KEEPCMT_SUB 2
|
2010-07-07 00:29:12 +00:00
|
|
|
|
#define KEEPCMT_EXP 3
|
2006-08-26 11:35:28 +00:00
|
|
|
|
|
2010-07-10 22:30:16 +00:00
|
|
|
|
//======================================================================
|
|
|
|
|
// Entry for each file processed; a stack of entries included
|
|
|
|
|
|
|
|
|
|
class VPreStream {
|
|
|
|
|
public:
|
|
|
|
|
FileLine* m_curFilelinep; // Current processing point (see also m_tokFilelinep)
|
2012-02-24 02:37:49 +00:00
|
|
|
|
V3PreLex* m_lexp; // Lexer, for resource tracking
|
2010-07-10 22:30:16 +00:00
|
|
|
|
deque<string> m_buffers; // Buffer of characters to process
|
|
|
|
|
int m_ignNewlines; // Ignore multiline newlines
|
|
|
|
|
bool m_eof; // "EOF" buffer
|
|
|
|
|
bool m_file; // Buffer is start of new file
|
|
|
|
|
int m_termState; // Termination fsm
|
2012-02-24 02:37:49 +00:00
|
|
|
|
VPreStream(FileLine* fl, V3PreLex* lexp)
|
|
|
|
|
: m_curFilelinep(fl), m_lexp(lexp),
|
|
|
|
|
m_ignNewlines(0),
|
2010-07-10 22:30:16 +00:00
|
|
|
|
m_eof(false), m_file(false), m_termState(0) {
|
2012-02-24 02:37:49 +00:00
|
|
|
|
lexStreamDepthAdd(1);
|
2010-07-10 22:30:16 +00:00
|
|
|
|
}
|
2012-02-24 02:37:49 +00:00
|
|
|
|
~VPreStream() {
|
|
|
|
|
lexStreamDepthAdd(-1);
|
|
|
|
|
}
|
|
|
|
|
private:
|
|
|
|
|
void lexStreamDepthAdd(int delta);
|
2010-07-10 22:30:16 +00:00
|
|
|
|
};
|
|
|
|
|
|
2010-02-27 00:50:44 +00:00
|
|
|
|
//======================================================================
|
2010-04-07 00:20:44 +00:00
|
|
|
|
// Class entry for each per-lexer state
|
2010-02-27 00:50:44 +00:00
|
|
|
|
|
2006-08-26 11:35:28 +00:00
|
|
|
|
class V3PreLex {
|
|
|
|
|
public: // Used only by V3PreLex.cpp and V3PreProc.cpp
|
2010-07-10 22:30:16 +00:00
|
|
|
|
V3PreProcImp* m_preimpp; // Preprocessor lexor belongs to
|
|
|
|
|
stack<VPreStream*> m_streampStack; // Stack of processing files
|
2012-02-24 02:37:49 +00:00
|
|
|
|
int m_streamDepth; // Depth of stream processing
|
2010-07-10 22:30:16 +00:00
|
|
|
|
YY_BUFFER_STATE m_bufferState; // Flex state
|
|
|
|
|
FileLine* m_tokFilelinep; // Starting position of current token
|
2006-08-26 11:35:28 +00:00
|
|
|
|
|
|
|
|
|
// State to lexer
|
2010-07-10 22:30:16 +00:00
|
|
|
|
static V3PreLex* s_currentLexp; ///< Current lexing point
|
|
|
|
|
int m_keepComments; ///< Emit comments in output text
|
|
|
|
|
int m_keepWhitespace; ///< Emit all whitespace in output text
|
|
|
|
|
bool m_pedantic; ///< Obey standard; don't Substitute `error
|
2006-08-26 11:35:28 +00:00
|
|
|
|
|
|
|
|
|
// State from lexer
|
2009-12-21 13:54:39 +00:00
|
|
|
|
int m_formalLevel; // Parenthesis counting inside def formals
|
2006-08-26 11:35:28 +00:00
|
|
|
|
int m_parenLevel; // Parenthesis counting inside def args
|
2010-01-28 14:41:24 +00:00
|
|
|
|
bool m_defCmtSlash; // /*...*/ comment in define had \ ending
|
2014-11-12 21:37:51 +00:00
|
|
|
|
bool m_defQuote; // Definition value inside quote
|
2006-08-26 11:35:28 +00:00
|
|
|
|
string m_defValue; // Definition value being built.
|
2010-07-07 00:29:12 +00:00
|
|
|
|
int m_enterExit; // For VL_LINE, the enter/exit level
|
2006-08-26 11:35:28 +00:00
|
|
|
|
|
|
|
|
|
// CONSTRUCTORS
|
2010-07-10 22:30:16 +00:00
|
|
|
|
V3PreLex(V3PreProcImp* preimpp, FileLine* filelinep) {
|
|
|
|
|
m_preimpp = preimpp;
|
2012-02-24 02:37:49 +00:00
|
|
|
|
m_streamDepth = 0;
|
2006-08-26 11:35:28 +00:00
|
|
|
|
m_keepComments = 0;
|
2010-07-10 22:30:16 +00:00
|
|
|
|
m_keepWhitespace = 1;
|
2006-08-26 11:35:28 +00:00
|
|
|
|
m_pedantic = false;
|
2009-12-21 13:54:39 +00:00
|
|
|
|
m_formalLevel = 0;
|
2006-08-26 11:35:28 +00:00
|
|
|
|
m_parenLevel = 0;
|
2014-11-12 21:37:51 +00:00
|
|
|
|
m_defQuote = false;
|
2010-01-28 14:41:24 +00:00
|
|
|
|
m_defCmtSlash = false;
|
2010-07-10 22:30:16 +00:00
|
|
|
|
m_tokFilelinep = filelinep;
|
2010-07-07 00:29:12 +00:00
|
|
|
|
m_enterExit = 0;
|
2010-07-10 22:30:16 +00:00
|
|
|
|
initFirstBuffer(filelinep);
|
2009-09-18 02:23:18 +00:00
|
|
|
|
}
|
|
|
|
|
~V3PreLex() {
|
2010-07-10 22:30:16 +00:00
|
|
|
|
while (!m_streampStack.empty()) { delete m_streampStack.top(); m_streampStack.pop(); }
|
|
|
|
|
yy_delete_buffer(m_bufferState); m_bufferState=NULL;
|
2006-08-26 11:35:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Called by V3PreLex.l from lexer
|
2010-07-10 22:30:16 +00:00
|
|
|
|
VPreStream* curStreamp() { return m_streampStack.top(); } // Can't be empty, "EOF" is on top
|
|
|
|
|
FileLine* curFilelinep() { return curStreamp()->m_curFilelinep; }
|
|
|
|
|
void curFilelinep(FileLine* fl) { curStreamp()->m_curFilelinep = fl; }
|
|
|
|
|
void appendDefValue(const char* textp, size_t len) { m_defValue.append(textp,len); }
|
2010-07-07 00:29:12 +00:00
|
|
|
|
void lineDirective(const char* textp);
|
2010-07-10 22:30:16 +00:00
|
|
|
|
void linenoInc() { if (curStreamp()->m_ignNewlines) curStreamp()->m_ignNewlines--;
|
|
|
|
|
else curFilelinep()->linenoInc(); }
|
2006-08-26 11:35:28 +00:00
|
|
|
|
// Called by V3PreProc.cpp to inform lexer
|
2008-04-25 14:01:50 +00:00
|
|
|
|
void pushStateDefArg(int level);
|
2009-05-11 15:57:43 +00:00
|
|
|
|
void pushStateDefForm();
|
2008-03-27 13:21:49 +00:00
|
|
|
|
void pushStateDefValue();
|
|
|
|
|
void pushStateIncFilename();
|
2010-07-10 22:30:16 +00:00
|
|
|
|
void scanNewFile(FileLine* filelinep);
|
|
|
|
|
void scanBytes(const string& str);
|
2010-04-07 00:20:44 +00:00
|
|
|
|
void scanBytesBack(const string& str);
|
|
|
|
|
size_t inputToLex(char* buf, size_t max_size);
|
2010-07-10 22:30:16 +00:00
|
|
|
|
/// Called by V3PreProc.cpp to get data from lexer
|
2009-09-18 02:23:18 +00:00
|
|
|
|
YY_BUFFER_STATE currentBuffer();
|
2010-07-10 22:30:16 +00:00
|
|
|
|
int lex();
|
2011-08-05 01:58:45 +00:00
|
|
|
|
int currentStartState() const;
|
2010-04-07 00:20:44 +00:00
|
|
|
|
void dumpSummary();
|
2009-09-18 02:23:18 +00:00
|
|
|
|
void dumpStack();
|
2010-07-10 22:30:16 +00:00
|
|
|
|
void unused();
|
2012-02-24 02:37:49 +00:00
|
|
|
|
// Called by VPreStream
|
|
|
|
|
void streamDepthAdd(int delta) { m_streamDepth += delta; }
|
|
|
|
|
int streamDepth() const { return m_streamDepth; }
|
2010-07-10 22:30:16 +00:00
|
|
|
|
/// Utility
|
|
|
|
|
static int debug();
|
|
|
|
|
static void debug(int level);
|
|
|
|
|
static string cleanDbgStrg(const string& in);
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
string currentUnreadChars();
|
|
|
|
|
string endOfStream(bool& againr);
|
|
|
|
|
void initFirstBuffer(FileLine* filelinep);
|
|
|
|
|
void scanSwitchStream(VPreStream* streamp);
|
2006-08-26 11:35:28 +00:00
|
|
|
|
};
|
|
|
|
|
|
2012-02-24 02:37:49 +00:00
|
|
|
|
inline void VPreStream::lexStreamDepthAdd(int delta) { m_lexp->streamDepthAdd(delta); }
|
|
|
|
|
|
2006-08-26 11:35:28 +00:00
|
|
|
|
#endif // Guard
|