File: VPreLex.h

package info (click to toggle)
libverilog-perl 3.460-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 4,188 kB
  • sloc: perl: 8,640; yacc: 3,362; cpp: 2,262; lex: 1,487; makefile: 8; fortran: 3
file content (236 lines) | stat: -rw-r--r-- 7,942 bytes parent folder | download
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
// -*- C++ -*-
//*************************************************************************
//
// Copyright 2000-2019 by Wilson Snyder.  This program is free software;
// 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.
//
// 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.
//
//*************************************************************************
/// \file
/// \brief Verilog::Preproc: Internal header for lex interfacing
///
/// Authors: Wilson Snyder
///
/// Code available from: http://www.veripool.org/verilog-perl
///
/// This header provides the interface between the lex proper VPreLex.l/.cpp
/// and the class implementation file VPreProc.cpp
/// It is not intended for user applications.
///
//*************************************************************************

#ifndef _VPREPROCLEX_H_		// Guard
#define _VPREPROCLEX_H_ 1

#include <deque>
#include <stack>

#include "VFileLine.h"

class VPreLex;
class VPreProcImp;

//======================================================================
// Token codes
// If changing, see VPreProc.cpp's VPreProcImp::tokenName()
#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
#define VP_LINE		264
#define VP_UNDEFINEALL	265

#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
#define VP_DEFFORM	309
#define VP_STRIFY	310
#define VP_BACKQUOTE	311
#define VP_SYMBOL_JOIN	312
#define VP_DEFREF_JOIN	313
#define VP_JOIN		314


#define VP_PSL		350

//======================================================================
// 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 VPreLex_create_buffer
# define yy_delete_buffer VPreLex_delete_buffer
# define yy_scan_buffer VPreLex_scan_buffer
# define yy_scan_string VPreLex_scan_string
# define yy_scan_bytes VPreLex_scan_bytes
# define yy_flex_debug VPreLex_flex_debug
# define yy_init_buffer VPreLex_init_buffer
# define yy_flush_buffer VPreLex_flush_buffer
# define yy_load_buffer_state VPreLex_load_buffer_state
# define yy_switch_to_buffer VPreLex_switch_to_buffer
# define yyin VPreLexin
# define yyleng VPreLexleng
# define yylex VPreLexlex
# define yyout VPreLexout
# define yyrestart VPreLexrestart
# define yytext VPreLextext
#endif

#ifndef yyourleng
# define yyourleng VPreLexourleng
# define yyourtext VPreLexourtext
#endif

#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*);

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

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
#define KEEPCMT_EXP 3

//======================================================================
// Entry for each file processed; a stack of entries included

class VPreStream {
public:
    VFileLine*		m_curFilelinep;	// Current processing point (see also m_tokFilelinep)
    VPreLex*		m_lexp;		// Lexer, for resource tracking
    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
    VPreStream(VFileLine* fl, VPreLex* lexp)
	: m_curFilelinep(fl), m_lexp(lexp),
	  m_ignNewlines(0),
	  m_eof(false), m_file(false), m_termState(0) {
	lexStreamDepthAdd(1);
    }
    ~VPreStream() {
	lexStreamDepthAdd(-1);
    }
private:
    void lexStreamDepthAdd(int delta);
};

//======================================================================
// Class entry for each per-lexer state

class VPreLex {
  public:	// Used only by VPreLex.cpp and VPreProc.cpp
    VPreProcImp*	m_preimpp;	// Preprocessor lexor belongs to
    stack<VPreStream*>	m_streampStack;	// Stack of processing files
    int			m_streamDepth;	// Depth of stream processing
    YY_BUFFER_STATE	m_bufferState;	// Flex state
    VFileLine*		m_tokFilelinep;	// Starting position of current token

    // State to lexer
    static VPreLex* 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
    bool	m_synthesis;	///< Remove translate_offs

    // State from lexer
    int		m_formalLevel;	///< Parenthesis counting inside def formals
    int		m_parenLevel;	///< Parenthesis counting inside def args
    bool	m_defCmtSlash;	///< /*...*/ comment in define had \ ending
    bool	m_defQuote;	///< Definition value inside quote
    string	m_defValue;	///< Definition value being built.
    int		m_enterExit;	///< For VL_LINE, the enter/exit level

    // CONSTRUCTORS
    VPreLex(VPreProcImp* preimpp, VFileLine* filelinep) {
	m_preimpp = preimpp;
	m_streamDepth = 0;
	m_keepComments = 0;
	m_keepWhitespace = 1;
	m_pedantic = false;
	m_synthesis = false;
	m_formalLevel = 0;
	m_parenLevel = 0;
	m_defQuote = false;
	m_defCmtSlash = false;
	m_tokFilelinep = filelinep;
	m_enterExit = 0;
	initFirstBuffer(filelinep);
    }
    ~VPreLex() {
	while (!m_streampStack.empty()) { delete m_streampStack.top(); m_streampStack.pop(); }
	yy_delete_buffer(m_bufferState); m_bufferState=NULL;
    }

    /// Called by VPreLex.l from lexer
    VPreStream* curStreamp() { return m_streampStack.top(); }  // Can't be empty, "EOF" is on top
    VFileLine* curFilelinep() { return curStreamp()->m_curFilelinep; }
    void curFilelinep(VFileLine* fl) { curStreamp()->m_curFilelinep = fl; }
    void appendDefValue(const char* textp, size_t len) { m_defValue.append(textp,len); }
    void lineDirective(const char* textp) { curFilelinep(curFilelinep()->lineDirective(textp, m_enterExit/*ref*/)); }
    void linenoInc() { if (curStreamp()->m_ignNewlines) curStreamp()->m_ignNewlines--;
	else curFilelinep(curFilelinep()->create(curFilelinep()->lineno()+1)); }
    /// Called by VPreProc.cpp to inform lexer
    void pushStateDefArg(int level);
    void pushStateDefForm();
    void pushStateDefValue();
    void pushStateIncFilename();
    void scanNewFile(VFileLine* filelinep);
    void scanBytes(const string& str);
    void scanBytesBack(const string& str);
    size_t inputToLex(char* buf, size_t max_size);
    /// Called by VPreProc.cpp to get data from lexer
    YY_BUFFER_STATE currentBuffer();
    int  lex();
    int	 currentStartState();
    void dumpSummary();
    void dumpStack();
    void unused();
    // Called by VPreStream
    void streamDepthAdd(int delta) { m_streamDepth += delta; }
    int streamDepth() const { return m_streamDepth; }
    /// Utility
    static int debug();
    static void debug(int level);
    static string cleanDbgStrg(const string& in);

private:
    string currentUnreadChars();
    string endOfStream(bool& againr);
    void initFirstBuffer(VFileLine* filelinep);
    void scanSwitchStream(VPreStream* streamp);
};

inline void VPreStream::lexStreamDepthAdd(int delta) { m_lexp->streamDepthAdd(delta); }

#endif // Guard