File: VParseLex.h

package info (click to toggle)
libverilog-perl 3.474-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 8,540 kB
  • sloc: perl: 8,675; yacc: 3,375; cpp: 2,262; lex: 1,500; makefile: 8; fortran: 3
file content (141 lines) | stat: -rw-r--r-- 4,569 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
// -*- C++ -*-
//*************************************************************************
//
// Copyright 2000-2020 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: Internal header for lex interfacing
///
/// Authors: Wilson Snyder
///
/// Code available from: https://www.veripool.org/verilog-perl
///
/// This header provides the interface between the lex proper VParseLex.l/.cpp
/// and the class implementation file VParse.cpp
/// It is not intended for user applications.
///
//*************************************************************************

#ifndef _VPARSELEX_H_		// Guard
#define _VPARSELEX_H_ 1

#include "VFileLine.h"
#include "VParseGrammar.h"

//======================================================================
// 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 VParseLex_create_buffer
# define yy_delete_buffer VParseLex_delete_buffer
# define yy_scan_buffer VParseLex_scan_buffer
# define yy_scan_string VParseLex_scan_string
# define yy_scan_bytes VParseLex_scan_bytes
# define yy_flex_debug VParseLex_flex_debug
# define yy_init_buffer VParseLex_init_buffer
# define yy_flush_buffer VParseLex_flush_buffer
# define yy_load_buffer_state VParseLex_load_buffer_state
# define yy_switch_to_buffer VParseLex_switch_to_buffer
# define yyin VParseLexin
# define yyleng VParseLexleng
# define yylex VParseLexlex
# define yyout VParseLexout
# define yyrestart VParseLexrestart
# define yytext VParseLextext
#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*);

YY_BUFFER_STATE yy_create_buffer (FILE *file, int size);
YY_BUFFER_STATE yy_scan_bytes(const char *bytes, int len);
void yy_switch_to_buffer(YY_BUFFER_STATE new_buffer);
void yy_delete_buffer(YY_BUFFER_STATE b);

class VParse;

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

class VParseLex {
  public:	// Used only by VParseLex.cpp and VParse.cpp
    VParse* 	m_parsep;	///< Current parser
    bool	m_inCellDefine;	///< In a `celldefine

    int		m_prevLexToken;		///< previous parsed token (for lexer)
    bool	m_ahead;		///< aheadToken is valid
    int		m_aheadToken;		///< Token we read ahead
    VParseBisonYYSType m_aheadVal;	///< aheadToken's value

    int		m_pvstate;		///< "pure virtual" detection

    // Parse state
    YY_BUFFER_STATE  m_yyState;	///< flex input state

    // State to lexer
    static VParseLex* s_currentLexp;	///< Current lexing point
    static VParseBisonYYSType* s_yylvalp;
    int	prevLexToken() { return m_prevLexToken; } // Parser -> lexer communication

    // CONSTRUCTORS
    VParseLex(VParse* parsep) {
	m_parsep = parsep;
	m_inCellDefine = false;
	m_prevLexToken = 0;
	m_ahead = false;
	m_pvstate = 0;

	m_yyState = yy_create_buffer(NULL, YY_BUF_SIZE);
	s_currentLexp = this;
	yyrestart(NULL);
	debug(0);
    }
    ~VParseLex() {
	yy_delete_buffer(m_yyState);
	s_currentLexp = NULL;
    }

    void restart() { yyrestart(NULL); }

    // Internal Utilities
    static bool symEscapeless(const char* textp, size_t leng) {
	// Are \ escapes needed to print this symbol?
	if (leng<1) return false;  // Probably not a valid identifier, but better than a core dump...
	if (!isalpha(textp[0]) && textp[0] != '_') return false;
	const char* cp = textp;
	for (size_t tleng=leng; tleng; tleng--, cp++) {
	    if (!isalnum(*cp) && *cp != '_') return false;
	}
	if (VParse::isKeyword(textp, leng)) return false;
	return true;
    }

    /// Called by VParse.cpp to inform lexer
    void unputString(const char* textp);
    void unputString(const char* textp, size_t length);

    void debug(int level);
    void language(const char* value);

    int lexToBison(VParseBisonYYSType* yylvalp);
private:
    void unused();
    int yylexReadTok();
    int lexToken(VParseBisonYYSType* yylvalp);
};

#endif // Guard