File: VParse.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 (261 lines) | stat: -rw-r--r-- 12,773 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
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
// -*- 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::Parse: Parses verilog code
///
/// Authors: Wilson Snyder
///
/// Code available from: http://www.veripool.org/verilog-perl
///
//*************************************************************************

#ifndef _VPREPROC_H_
#define _VPREPROC_H_ 1

#include <string>
#include <map>
#include <set>
#include <deque>
#include <iostream>
using namespace std;
#include "VFileLine.h"
#include "VSymTable.h"

class VParseLex;  // Be sure not to include it, or the Bison class will get upset
class VParseGrammar;  // Be sure not to include it, or the Lex class will get upset
struct VParseBisonYYSType;

struct av;

struct VParseHashElem {
    const char* keyp;
    enum {ELEM_STR, ELEM_INT} val_type;
    string val_str;  // When val_type==ELEM_STR
    int val_int;  // When val_type==ELEM_INT
    VParseHashElem() { keyp = NULL; }
    ~VParseHashElem() {}
};

//**********************************************************************
// VParse

class VParse {
private:
    // MEMBERS
    // Mode
    bool	m_sigParser;	///< SigParser not simple Verilog::Parser

    // State
    VFileLine*	m_inFilelinep;	///< Next token's starting point
    int		m_debug;	///< Debugging level
    VParseLex*	m_lexp;		///< Current lexer state (NULL = closed)
    VParseGrammar* m_grammarp;	///< Current bison state (NULL = closed)
    bool	m_eof;		///< At end of file
    bool	m_callbackMasterEna; ///< Callbacks are enabled

    bool	m_useUnreadback;///< Need m_unreadback tracking
    bool	m_useProtected;	///< Need `protected tracking
    bool	m_usePinselects;///< Need bit-select parsing
    string	m_unreadback;	///< Otherwise unprocessed whitespace before current token
    deque<string> m_buffers;	///< Buffer of characters to process

    int		m_anonNum;	///< Number of next anonymous object

    VSymStack	m_syms;		///< Symbol stack

    VAstEnt*	m_symTableNextId;	///< Symbol table for next lexer lookup

public:  // But for internalish use only
    // METHODS
    int lexToBison(VParseBisonYYSType* yylvalp);
    bool eofToLex() const { return m_eof && m_buffers.empty(); }
    bool inCellDefine() const;
    size_t inputToLex(char* buf, size_t max_size);

    // Symbol table
    VSymStack&	syms() { return m_syms; }
    VAstEnt* symTableNextId() const { return m_symTableNextId; }
    void symTableNextId(VAstEnt* entp) {
	if (debug()) {
	    if (entp) cout <<"symTableNextId under "<<entp<<"-"<<entp->type().ascii()<<endl;
	    else cout <<"symTableNextId under NULL"<<endl;
	}
	m_symTableNextId = entp;
    }
    string symObjofUpward() {
	return m_syms.objofUpward();
    }
    void symPushNew(VAstType type, const string& name) {
	symPushNewUnder(type, name, NULL);
    }
    void symPushNewUnder(VAstType type, const string& name, VAstEnt* parentp) {
	if (!parentp) parentp = m_syms.currentSymp();
	m_syms.pushScope(parentp->replaceInsert(type,name));
    }
    void symPushNewAnon(VAstType type) {
	string name = "__anon";
	name += type.ascii() + cvtToStr(++m_anonNum);
	symPushNew(type,name);
    }
    void symPopScope(VAstType type) {
	if (m_syms.curType() != type) {
	    string msg = (string)("Symbols suggest ending a '")+m_syms.curType().ascii()+"' but parser thinks ending a '"+type.ascii()+"'";
	    this->error(msg);
	    return;
	}
	m_syms.popScope(inFilelinep());
    }

private:
    void fakeBison();

public:
    // CONSTRUCTORS
    VParse(VFileLine* filelinep, av* symsp,
	   bool sigParser, bool useUnreadbackFlag, bool useProtected, bool usePinselects);
    virtual ~VParse();

    // ACCESSORS
    /// Insert given file into this point in input stream
    int debug() const { return m_debug; }	///< Set debugging level
    void debug(int level);			///< Set debugging level
    void parse(const string& text);		///< Add given text to
    void setEof();				///< Got a end of file
    bool sigParser() const { return m_sigParser; }
    void language(const char* valuep);
    void callbackMasterEna(bool flag) { m_callbackMasterEna=flag; }
    bool callbackMasterEna() const { return m_callbackMasterEna; }
    bool useProtected() const { return m_useProtected; }
    bool usePinSelects() const { return m_usePinselects; }

    VFileLine* inFilelinep() const;		///< File/Line number for last callback
    void inFileline(const string& filename, int lineno) { m_inFilelinep = m_inFilelinep->create(filename, lineno); }
    void inFilelineInc() { m_inFilelinep = inFilelinep()->create(inFilelinep()->lineno()+1); }
    void inLineDirective(const char* text) { int ign; m_inFilelinep = inFilelinep()->lineDirective(text, ign/*ref*/); }

    string unreadback() const { return (m_useUnreadback ? m_unreadback : "new(...,use_unreadback=>0) was used"); }
    void unreadback(const string& text) { if (m_useUnreadback && callbackMasterEna()) m_unreadback = text; }
    void unreadbackCat(const string& text) { if (m_useUnreadback && callbackMasterEna()) m_unreadback += text; }
    void unreadbackCat(const char* textp, size_t len) { unreadbackCat(string(textp,len)); }

    // The default behavior is to pass all unknown `defines right through.
    // This lets the user determine how to report the errors.  It also nicely
    // allows `celldefine and such to remain in the output stream.

    // CONTROL METHODS
    // These options control how the parsing proceeds

    // CALLBACK METHODS
    // This probably will want to be overridden for given child users of this class.

    // CALLBACKGEN_H_VIRTUAL_0
    // CALLBACKGEN_GENERATED_BEGIN - GENERATED AUTOMATICALLY by callbackgen
    // Verilog::Parser Callback methods
    virtual void attributeCb(VFileLine* fl, const string& text) = 0;
    virtual void commentCb(VFileLine* fl, const string& text) = 0;
    virtual void endparseCb(VFileLine* fl, const string& text) = 0;
    virtual void keywordCb(VFileLine* fl, const string& text) = 0;
    virtual void numberCb(VFileLine* fl, const string& text) = 0;
    virtual void operatorCb(VFileLine* fl, const string& text) = 0;
    virtual void preprocCb(VFileLine* fl, const string& text) = 0;
    virtual void stringCb(VFileLine* fl, const string& text) = 0;
    virtual void symbolCb(VFileLine* fl, const string& text) = 0;
    virtual void sysfuncCb(VFileLine* fl, const string& text) = 0;
    // Verilog::SigParser Callback methods
    virtual void classCb(VFileLine* fl, const string& kwd, const string& name, const string& virt) = 0;
    virtual void contassignCb(VFileLine* fl, const string& kwd, const string& lhs, const string& rhs) = 0;
    virtual void covergroupCb(VFileLine* fl, const string& kwd, const string& name) = 0;
    virtual void defparamCb(VFileLine* fl, const string& kwd, const string& lhs, const string& rhs) = 0;
    virtual void endcellCb(VFileLine* fl, const string& kwd) = 0;
    virtual void endclassCb(VFileLine* fl, const string& kwd) = 0;
    virtual void endgroupCb(VFileLine* fl, const string& kwd) = 0;
    virtual void endinterfaceCb(VFileLine* fl, const string& kwd) = 0;
    virtual void endmodportCb(VFileLine* fl, const string& kwd) = 0;
    virtual void endmoduleCb(VFileLine* fl, const string& kwd) = 0;
    virtual void endpackageCb(VFileLine* fl, const string& kwd) = 0;
    virtual void endprogramCb(VFileLine* fl, const string& kwd) = 0;
    virtual void endtaskfuncCb(VFileLine* fl, const string& kwd) = 0;
    virtual void functionCb(VFileLine* fl, const string& kwd, const string& name, const string& data_type) = 0;
    virtual void importCb(VFileLine* fl, const string& package, const string& id) = 0;
    virtual void instantCb(VFileLine* fl, const string& mod, const string& cell, const string& range) = 0;
    virtual void interfaceCb(VFileLine* fl, const string& kwd, const string& name) = 0;
    virtual void modportCb(VFileLine* fl, const string& kwd, const string& name) = 0;
    virtual void moduleCb(VFileLine* fl, const string& kwd, const string& name, bool, bool celldefine) = 0;
    virtual void packageCb(VFileLine* fl, const string& kwd, const string& name) = 0;
    virtual void parampinCb(VFileLine* fl, const string& name, const string& conn, int index) = 0;
    virtual void pinCb(VFileLine* fl, const string& name, const string& conn, int index) = 0;
    virtual void pinselectsCb(VFileLine* fl, const string& name, unsigned int arraycnt2, unsigned int elemcnt2, const VParseHashElem* conns2, int index) = 0;
    virtual void portCb(VFileLine* fl, const string& name, const string& objof, const string& direction, const string& data_type
	, const string& array, int index) = 0;
    virtual void programCb(VFileLine* fl, const string& kwd, const string& name) = 0;
    virtual void taskCb(VFileLine* fl, const string& kwd, const string& name) = 0;
    virtual void varCb(VFileLine* fl, const string& kwd, const string& name, const string& objof, const string& net
	, const string& data_type, const string& array, const string& value) = 0;
    // CALLBACKGEN_GENERATED_END - GENERATED AUTOMATICALLY by callbackgen

    // CALLBACKGEN_KEYWORDS
    // CALLBACKGEN_GENERATED_BEGIN - GENERATED AUTOMATICALLY by callbackgen
    static bool isKeyword(const char* kwd, int leng) {
	static set<string> s_map;
	if (s_map.empty()) {
	    const char* kwds[] = {
		"accept_on","alias","always","always_comb","always_ff","always_latch","and",
		"assert","assign","assume","automatic","before","begin","bind",
		"bins","binsof","bit","break","buf","bufif0","bufif1",
		"byte","case","casex","casez","cell","chandle","checker",
		"class","clocking","cmos","config","const","constraint","context",
		"continue","cover","covergroup","coverpoint","cross","deassign","default",
		"defparam","design","disable","dist","do","edge","else",
		"end","endcase","endchecker","endclass","endclocking","endconfig","endfunction",
		"endgenerate","endgroup","endinterface","endmodule","endpackage","endprimitive","endprogram",
		"endproperty","endsequence","endspecify","endtable","endtask","enum","event",
		"eventually","expect","export","extends","extern","final","first_match",
		"for","force","foreach","forever","fork","forkjoin","function",
		"generate","genvar","global","highz0","highz1","if","iff",
		"ifnone","ignore_bins","illegal_bins","implements","implies","import","incdir",
		"include","initial","inout","input","inside","instance","int",
		"integer","interconnect","interface","intersect","join","join_any","join_none",
		"large","let","liblist","library","local","localparam","logic",
		"longint","macromodule","matches","medium","modport","module","nand",
		"negedge","nettype","new","nexttime","nmos","nor","noshowcancelled",
		"not","notif0","notif1","null","or","output","package",
		"packed","parameter","pmos","posedge","primitive","priority","program",
		"property","protected","pull0","pull1","pulldown","pullup","pulsestyle_ondetect",
		"pulsestyle_onevent","pure","rand","randc","randcase","randsequence","rcmos",
		"real","realtime","ref","reg","reject_on","release","repeat",
		"restrict","return","rnmos","rpmos","rtran","rtranif0","rtranif1",
		"s_always","s_eventually","s_nexttime","s_until","s_until_with","scalared","sequence",
		"shortint","shortreal","showcancelled","signed","small","soft","solve",
		"specify","specparam","static","strength","string","strong","strong0",
		"strong1","struct","super","supply0","supply1","sync_accept_on","sync_reject_on",
		"table","tagged","task","this","throughout","time","timeprecision",
		"timeunit","tran","tranif0","tranif1","tri","tri0","tri1",
		"triand","trior","trireg","type","typedef","union","unique",
		"unique0","unsigned","until","until_with","untyped","use","uwire",
		"var","vectored","virtual","void","wait","wait_order","wand",
		"weak","weak0","weak1","while","wildcard","wire","with",
		"within","wor","xnor","xor",""};
	    for (const char** k=kwds; **k; k++) s_map.insert(*k);
	}
	string str(kwd,leng);
	return s_map.end() != s_map.find(str);
    }
    // CALLBACKGEN_GENERATED_END - GENERATED AUTOMATICALLY by callbackgen

    // UTILITIES
    void error(const string& msg) { inFilelinep()->error(msg); }	///< Report a error
    void fatal(const string& msg) { inFilelinep()->fatal(msg); }	///< Report a fatal error
};

#endif // Guard