ctags.rb 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +2 -0
- data/Rakefile +23 -0
- data/ctags.rb.gemspec +23 -0
- data/ext/.gitignore +3 -0
- data/ext/extconf.rb +15 -0
- data/ext/vendor/exuberant-ctags/.gitignore +6 -0
- data/ext/vendor/exuberant-ctags/.indent.pro +31 -0
- data/ext/vendor/exuberant-ctags/COPYING +340 -0
- data/ext/vendor/exuberant-ctags/EXTENDING.html +386 -0
- data/ext/vendor/exuberant-ctags/FAQ +371 -0
- data/ext/vendor/exuberant-ctags/INSTALL +215 -0
- data/ext/vendor/exuberant-ctags/INSTALL.oth +73 -0
- data/ext/vendor/exuberant-ctags/MAINTAINERS +88 -0
- data/ext/vendor/exuberant-ctags/Makefile.in +222 -0
- data/ext/vendor/exuberant-ctags/NEWS +871 -0
- data/ext/vendor/exuberant-ctags/README +73 -0
- data/ext/vendor/exuberant-ctags/ant.c +42 -0
- data/ext/vendor/exuberant-ctags/argproc.c +505 -0
- data/ext/vendor/exuberant-ctags/args.c +274 -0
- data/ext/vendor/exuberant-ctags/args.h +63 -0
- data/ext/vendor/exuberant-ctags/asm.c +387 -0
- data/ext/vendor/exuberant-ctags/asp.c +328 -0
- data/ext/vendor/exuberant-ctags/awk.c +81 -0
- data/ext/vendor/exuberant-ctags/basic.c +203 -0
- data/ext/vendor/exuberant-ctags/beta.c +321 -0
- data/ext/vendor/exuberant-ctags/c.c +2932 -0
- data/ext/vendor/exuberant-ctags/cobol.c +50 -0
- data/ext/vendor/exuberant-ctags/config.h.in +277 -0
- data/ext/vendor/exuberant-ctags/configure +7704 -0
- data/ext/vendor/exuberant-ctags/configure.ac +532 -0
- data/ext/vendor/exuberant-ctags/ctags.1 +1186 -0
- data/ext/vendor/exuberant-ctags/ctags.h +28 -0
- data/ext/vendor/exuberant-ctags/ctags.html +2087 -0
- data/ext/vendor/exuberant-ctags/ctags.spec +40 -0
- data/ext/vendor/exuberant-ctags/debug.c +113 -0
- data/ext/vendor/exuberant-ctags/debug.h +70 -0
- data/ext/vendor/exuberant-ctags/descrip.mms +68 -0
- data/ext/vendor/exuberant-ctags/dosbatch.c +42 -0
- data/ext/vendor/exuberant-ctags/e_amiga.h +24 -0
- data/ext/vendor/exuberant-ctags/e_djgpp.h +47 -0
- data/ext/vendor/exuberant-ctags/e_mac.h +143 -0
- data/ext/vendor/exuberant-ctags/e_msoft.h +76 -0
- data/ext/vendor/exuberant-ctags/e_os2.h +37 -0
- data/ext/vendor/exuberant-ctags/e_qdos.h +34 -0
- data/ext/vendor/exuberant-ctags/e_riscos.h +58 -0
- data/ext/vendor/exuberant-ctags/e_vms.h +31 -0
- data/ext/vendor/exuberant-ctags/eiffel.c +1352 -0
- data/ext/vendor/exuberant-ctags/entry.c +847 -0
- data/ext/vendor/exuberant-ctags/entry.h +103 -0
- data/ext/vendor/exuberant-ctags/erlang.c +189 -0
- data/ext/vendor/exuberant-ctags/flex.c +2243 -0
- data/ext/vendor/exuberant-ctags/fortran.c +2197 -0
- data/ext/vendor/exuberant-ctags/general.h +127 -0
- data/ext/vendor/exuberant-ctags/get.c +669 -0
- data/ext/vendor/exuberant-ctags/get.h +50 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/all-wcprops +47 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/entries +112 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/README.txt.svn-base +5 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regcomp.c.svn-base +3818 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex.c.svn-base +74 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex.h.svn-base +575 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex_internal.c.svn-base +1713 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex_internal.h.svn-base +773 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regexec.c.svn-base +4338 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/README.txt +5 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/regcomp.c +3818 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/regex.c +74 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/regex.h +575 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/regex_internal.c +1713 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/regex_internal.h +773 -0
- data/ext/vendor/exuberant-ctags/gnu_regex/regexec.c +4338 -0
- data/ext/vendor/exuberant-ctags/html.c +49 -0
- data/ext/vendor/exuberant-ctags/jscript.c +1572 -0
- data/ext/vendor/exuberant-ctags/keyword.c +258 -0
- data/ext/vendor/exuberant-ctags/keyword.h +34 -0
- data/ext/vendor/exuberant-ctags/lisp.c +139 -0
- data/ext/vendor/exuberant-ctags/lregex.c +704 -0
- data/ext/vendor/exuberant-ctags/lua.c +133 -0
- data/ext/vendor/exuberant-ctags/mac.c +273 -0
- data/ext/vendor/exuberant-ctags/magic.diff +21 -0
- data/ext/vendor/exuberant-ctags/main.c +584 -0
- data/ext/vendor/exuberant-ctags/main.h +32 -0
- data/ext/vendor/exuberant-ctags/maintainer.mak +476 -0
- data/ext/vendor/exuberant-ctags/make.c +217 -0
- data/ext/vendor/exuberant-ctags/matlab.c +44 -0
- data/ext/vendor/exuberant-ctags/mk_bc3.mak +46 -0
- data/ext/vendor/exuberant-ctags/mk_bc5.mak +49 -0
- data/ext/vendor/exuberant-ctags/mk_djg.mak +18 -0
- data/ext/vendor/exuberant-ctags/mk_manx.mak +65 -0
- data/ext/vendor/exuberant-ctags/mk_mingw.mak +31 -0
- data/ext/vendor/exuberant-ctags/mk_mpw.mak +130 -0
- data/ext/vendor/exuberant-ctags/mk_mvc.mak +40 -0
- data/ext/vendor/exuberant-ctags/mk_os2.mak +104 -0
- data/ext/vendor/exuberant-ctags/mk_qdos.mak +100 -0
- data/ext/vendor/exuberant-ctags/mk_sas.mak +63 -0
- data/ext/vendor/exuberant-ctags/mkinstalldirs +40 -0
- data/ext/vendor/exuberant-ctags/ocaml.c +1842 -0
- data/ext/vendor/exuberant-ctags/options.c +1842 -0
- data/ext/vendor/exuberant-ctags/options.h +155 -0
- data/ext/vendor/exuberant-ctags/parse.c +677 -0
- data/ext/vendor/exuberant-ctags/parse.h +129 -0
- data/ext/vendor/exuberant-ctags/parsers.h +63 -0
- data/ext/vendor/exuberant-ctags/pascal.c +267 -0
- data/ext/vendor/exuberant-ctags/perl.c +382 -0
- data/ext/vendor/exuberant-ctags/php.c +237 -0
- data/ext/vendor/exuberant-ctags/python.c +771 -0
- data/ext/vendor/exuberant-ctags/qdos.c +106 -0
- data/ext/vendor/exuberant-ctags/read.c +569 -0
- data/ext/vendor/exuberant-ctags/read.h +116 -0
- data/ext/vendor/exuberant-ctags/readtags.c +959 -0
- data/ext/vendor/exuberant-ctags/readtags.h +252 -0
- data/ext/vendor/exuberant-ctags/rexx.c +39 -0
- data/ext/vendor/exuberant-ctags/routines.c +891 -0
- data/ext/vendor/exuberant-ctags/routines.h +134 -0
- data/ext/vendor/exuberant-ctags/ruby.c +408 -0
- data/ext/vendor/exuberant-ctags/scheme.c +111 -0
- data/ext/vendor/exuberant-ctags/sh.c +115 -0
- data/ext/vendor/exuberant-ctags/slang.c +41 -0
- data/ext/vendor/exuberant-ctags/sml.c +212 -0
- data/ext/vendor/exuberant-ctags/sort.c +230 -0
- data/ext/vendor/exuberant-ctags/sort.h +32 -0
- data/ext/vendor/exuberant-ctags/source.mak +122 -0
- data/ext/vendor/exuberant-ctags/sql.c +2112 -0
- data/ext/vendor/exuberant-ctags/strlist.c +281 -0
- data/ext/vendor/exuberant-ctags/strlist.h +54 -0
- data/ext/vendor/exuberant-ctags/tcl.c +116 -0
- data/ext/vendor/exuberant-ctags/tex.c +524 -0
- data/ext/vendor/exuberant-ctags/verilog.c +340 -0
- data/ext/vendor/exuberant-ctags/vhdl.c +835 -0
- data/ext/vendor/exuberant-ctags/vim.c +636 -0
- data/ext/vendor/exuberant-ctags/vstring.c +232 -0
- data/ext/vendor/exuberant-ctags/vstring.h +85 -0
- data/ext/vendor/exuberant-ctags/yacc.c +40 -0
- data/lib/ctags/exuberant.rb +45 -0
- data/lib/ctags/version.rb +3 -0
- data/lib/ctags.rb +6 -0
- data/test/test_ctags.rb +24 -0
- metadata +233 -0
|
@@ -0,0 +1,835 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* $Id: vhdl.c 652 2008-04-18 03:51:47Z elliotth $
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2008, Nicolas Vincent
|
|
5
|
+
*
|
|
6
|
+
* This source code is released for free distribution under the terms of the
|
|
7
|
+
* GNU General Public License.
|
|
8
|
+
*
|
|
9
|
+
* This module contains functions for generating tags for VHDL files.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
* INCLUDE FILES
|
|
14
|
+
*/
|
|
15
|
+
#include "general.h" /* must always come first */
|
|
16
|
+
|
|
17
|
+
#include <ctype.h> /* to define isalpha () */
|
|
18
|
+
#include <string.h>
|
|
19
|
+
#include <setjmp.h>
|
|
20
|
+
|
|
21
|
+
#include "debug.h"
|
|
22
|
+
#include "entry.h"
|
|
23
|
+
#include "keyword.h"
|
|
24
|
+
#include "parse.h"
|
|
25
|
+
#include "read.h"
|
|
26
|
+
#include "routines.h"
|
|
27
|
+
#include "vstring.h"
|
|
28
|
+
|
|
29
|
+
/*
|
|
30
|
+
* MACROS
|
|
31
|
+
*/
|
|
32
|
+
#define isType(token,t) (boolean) ((token)->type == (t))
|
|
33
|
+
#define isKeyword(token,k) (boolean) ((token)->keyword == (k))
|
|
34
|
+
|
|
35
|
+
/*
|
|
36
|
+
* DATA DECLARATIONS
|
|
37
|
+
*/
|
|
38
|
+
typedef enum eException { ExceptionNone, ExceptionEOF } exception_t;
|
|
39
|
+
|
|
40
|
+
/*
|
|
41
|
+
* Used to specify type of keyword.
|
|
42
|
+
*/
|
|
43
|
+
typedef enum eKeywordId {
|
|
44
|
+
KEYWORD_NONE = -1,
|
|
45
|
+
KEYWORD_ABS,
|
|
46
|
+
KEYWORD_ACCESS,
|
|
47
|
+
KEYWORD_AFTER,
|
|
48
|
+
KEYWORD_ALIAS,
|
|
49
|
+
KEYWORD_ALL,
|
|
50
|
+
KEYWORD_AND,
|
|
51
|
+
KEYWORD_ARCHITECTURE,
|
|
52
|
+
KEYWORD_ARRAY,
|
|
53
|
+
KEYWORD_ASSERT,
|
|
54
|
+
KEYWORD_ATTRIBUTE,
|
|
55
|
+
KEYWORD_BEGIN,
|
|
56
|
+
KEYWORD_BLOCK,
|
|
57
|
+
KEYWORD_BODY,
|
|
58
|
+
KEYWORD_BUFFER,
|
|
59
|
+
KEYWORD_BUS,
|
|
60
|
+
KEYWORD_CASE,
|
|
61
|
+
KEYWORD_COMPONENT,
|
|
62
|
+
KEYWORD_CONFIGURATION,
|
|
63
|
+
KEYWORD_CONSTANT,
|
|
64
|
+
KEYWORD_DISCONNECT,
|
|
65
|
+
KEYWORD_DOWNTO,
|
|
66
|
+
KEYWORD_ELSE,
|
|
67
|
+
KEYWORD_ELSIF,
|
|
68
|
+
KEYWORD_END,
|
|
69
|
+
KEYWORD_ENTITY,
|
|
70
|
+
KEYWORD_EXIT,
|
|
71
|
+
KEYWORD_FILE,
|
|
72
|
+
KEYWORD_FOR,
|
|
73
|
+
KEYWORD_FUNCTION,
|
|
74
|
+
KEYWORD_GENERATE,
|
|
75
|
+
KEYWORD_GENERIC,
|
|
76
|
+
KEYWORD_GROUP,
|
|
77
|
+
KEYWORD_GUARDED,
|
|
78
|
+
KEYWORD_IF,
|
|
79
|
+
KEYWORD_IMPURE,
|
|
80
|
+
KEYWORD_IN,
|
|
81
|
+
KEYWORD_INERTIAL,
|
|
82
|
+
KEYWORD_INOUT,
|
|
83
|
+
KEYWORD_IS,
|
|
84
|
+
KEYWORD_LABEL,
|
|
85
|
+
KEYWORD_LIBRARY,
|
|
86
|
+
KEYWORD_LINKAGE,
|
|
87
|
+
KEYWORD_LITERAL,
|
|
88
|
+
KEYWORD_LOOP,
|
|
89
|
+
KEYWORD_MAP,
|
|
90
|
+
KEYWORD_MOD,
|
|
91
|
+
KEYWORD_NAND,
|
|
92
|
+
KEYWORD_NEW,
|
|
93
|
+
KEYWORD_NEXT,
|
|
94
|
+
KEYWORD_NOR,
|
|
95
|
+
KEYWORD_NOT,
|
|
96
|
+
KEYWORD_NULL,
|
|
97
|
+
KEYWORD_OF,
|
|
98
|
+
KEYWORD_ON,
|
|
99
|
+
KEYWORD_OPEN,
|
|
100
|
+
KEYWORD_OR,
|
|
101
|
+
KEYWORD_OTHERS,
|
|
102
|
+
KEYWORD_OUT,
|
|
103
|
+
KEYWORD_PACKAGE,
|
|
104
|
+
KEYWORD_PORT,
|
|
105
|
+
KEYWORD_POSTPONED,
|
|
106
|
+
KEYWORD_PROCEDURE,
|
|
107
|
+
KEYWORD_PROCESS,
|
|
108
|
+
KEYWORD_PURE,
|
|
109
|
+
KEYWORD_RANGE,
|
|
110
|
+
KEYWORD_RECORD,
|
|
111
|
+
KEYWORD_REGISTER,
|
|
112
|
+
KEYWORD_REJECT,
|
|
113
|
+
KEYWORD_RETURN,
|
|
114
|
+
KEYWORD_ROL,
|
|
115
|
+
KEYWORD_ROR,
|
|
116
|
+
KEYWORD_SELECT,
|
|
117
|
+
KEYWORD_SEVERITY,
|
|
118
|
+
KEYWORD_SIGNAL,
|
|
119
|
+
KEYWORD_SHARED,
|
|
120
|
+
KEYWORD_SLA,
|
|
121
|
+
KEYWORD_SLI,
|
|
122
|
+
KEYWORD_SRA,
|
|
123
|
+
KEYWORD_SRL,
|
|
124
|
+
KEYWORD_SUBTYPE,
|
|
125
|
+
KEYWORD_THEN,
|
|
126
|
+
KEYWORD_TO,
|
|
127
|
+
KEYWORD_TRANSPORT,
|
|
128
|
+
KEYWORD_TYPE,
|
|
129
|
+
KEYWORD_UNAFFECTED,
|
|
130
|
+
KEYWORD_UNITS,
|
|
131
|
+
KEYWORD_UNTIL,
|
|
132
|
+
KEYWORD_USE,
|
|
133
|
+
KEYWORD_VARIABLE,
|
|
134
|
+
KEYWORD_WAIT,
|
|
135
|
+
KEYWORD_WHEN,
|
|
136
|
+
KEYWORD_WHILE,
|
|
137
|
+
KEYWORD_WITH,
|
|
138
|
+
KEYWORD_XNOR,
|
|
139
|
+
KEYWORD_XOR
|
|
140
|
+
} keywordId;
|
|
141
|
+
|
|
142
|
+
/* Used to determine whether keyword is valid for the current language and
|
|
143
|
+
* what its ID is.
|
|
144
|
+
*/
|
|
145
|
+
typedef struct sKeywordDesc {
|
|
146
|
+
const char *name;
|
|
147
|
+
keywordId id;
|
|
148
|
+
} keywordDesc;
|
|
149
|
+
|
|
150
|
+
typedef enum eTokenType {
|
|
151
|
+
TOKEN_NONE, /* none */
|
|
152
|
+
TOKEN_OPEN_PAREN, /* ( */
|
|
153
|
+
TOKEN_CLOSE_PAREN, /* ) */
|
|
154
|
+
TOKEN_COMMA, /* the comma character */
|
|
155
|
+
TOKEN_IDENTIFIER,
|
|
156
|
+
TOKEN_KEYWORD,
|
|
157
|
+
TOKEN_PERIOD, /* . */
|
|
158
|
+
TOKEN_OPERATOR,
|
|
159
|
+
TOKEN_SEMICOLON, /* the semicolon character */
|
|
160
|
+
TOKEN_STRING
|
|
161
|
+
} tokenType;
|
|
162
|
+
|
|
163
|
+
typedef struct sTokenInfo {
|
|
164
|
+
tokenType type;
|
|
165
|
+
keywordId keyword;
|
|
166
|
+
vString *string; /* the name of the token */
|
|
167
|
+
vString *scope;
|
|
168
|
+
unsigned long lineNumber; /* line number of tag */
|
|
169
|
+
fpos_t filePosition; /* file position of line containing name */
|
|
170
|
+
} tokenInfo;
|
|
171
|
+
|
|
172
|
+
/*
|
|
173
|
+
* DATA DEFINITIONS
|
|
174
|
+
*/
|
|
175
|
+
static int Lang_vhdl;
|
|
176
|
+
static jmp_buf Exception;
|
|
177
|
+
|
|
178
|
+
/* Used to index into the VhdlKinds table. */
|
|
179
|
+
typedef enum {
|
|
180
|
+
VHDLTAG_UNDEFINED = -1,
|
|
181
|
+
VHDLTAG_CONSTANT,
|
|
182
|
+
VHDLTAG_TYPE,
|
|
183
|
+
VHDLTAG_SUBTYPE,
|
|
184
|
+
VHDLTAG_RECORD,
|
|
185
|
+
VHDLTAG_ENTITY,
|
|
186
|
+
VHDLTAG_COMPONENT,
|
|
187
|
+
VHDLTAG_PROTOTYPE,
|
|
188
|
+
VHDLTAG_FUNCTION,
|
|
189
|
+
VHDLTAG_PROCEDURE,
|
|
190
|
+
VHDLTAG_PACKAGE,
|
|
191
|
+
VHDLTAG_LOCAL
|
|
192
|
+
} vhdlKind;
|
|
193
|
+
|
|
194
|
+
static kindOption VhdlKinds[] = {
|
|
195
|
+
{TRUE, 'c', "constant", "constant declarations"},
|
|
196
|
+
{TRUE, 't', "type", "type definitions"},
|
|
197
|
+
{TRUE, 'T', "subtype", "subtype definitions"},
|
|
198
|
+
{TRUE, 'r', "record", "record names"},
|
|
199
|
+
{TRUE, 'e', "entity", "entity declarations"},
|
|
200
|
+
{FALSE, 'C', "component", "component declarations"},
|
|
201
|
+
{FALSE, 'd', "prototype", "prototypes"},
|
|
202
|
+
{TRUE, 'f', "function", "function prototypes and declarations"},
|
|
203
|
+
{TRUE, 'p', "procedure", "procedure prototypes and declarations"},
|
|
204
|
+
{TRUE, 'P', "package", "package definitions"},
|
|
205
|
+
{FALSE, 'l', "local", "local definitions"}
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
static keywordDesc VhdlKeywordTable[] = {
|
|
209
|
+
{"abs", KEYWORD_ABS},
|
|
210
|
+
{"access", KEYWORD_ACCESS},
|
|
211
|
+
{"after", KEYWORD_AFTER},
|
|
212
|
+
{"alias", KEYWORD_ALIAS},
|
|
213
|
+
{"all", KEYWORD_ALL},
|
|
214
|
+
{"and", KEYWORD_AND},
|
|
215
|
+
{"architecture", KEYWORD_ARCHITECTURE},
|
|
216
|
+
{"array", KEYWORD_ARRAY},
|
|
217
|
+
{"assert", KEYWORD_ASSERT},
|
|
218
|
+
{"attribute", KEYWORD_ATTRIBUTE},
|
|
219
|
+
{"begin", KEYWORD_BEGIN},
|
|
220
|
+
{"block", KEYWORD_BLOCK},
|
|
221
|
+
{"body", KEYWORD_BODY},
|
|
222
|
+
{"buffer", KEYWORD_BUFFER},
|
|
223
|
+
{"bus", KEYWORD_BUS},
|
|
224
|
+
{"case", KEYWORD_CASE},
|
|
225
|
+
{"component", KEYWORD_COMPONENT},
|
|
226
|
+
{"configuration", KEYWORD_CONFIGURATION},
|
|
227
|
+
{"constant", KEYWORD_CONSTANT},
|
|
228
|
+
{"disconnect", KEYWORD_DISCONNECT},
|
|
229
|
+
{"downto", KEYWORD_DOWNTO},
|
|
230
|
+
{"else", KEYWORD_ELSE},
|
|
231
|
+
{"elsif", KEYWORD_ELSIF},
|
|
232
|
+
{"end", KEYWORD_END},
|
|
233
|
+
{"entity", KEYWORD_ENTITY},
|
|
234
|
+
{"exit", KEYWORD_EXIT},
|
|
235
|
+
{"file", KEYWORD_FILE},
|
|
236
|
+
{"for", KEYWORD_FOR},
|
|
237
|
+
{"function", KEYWORD_FUNCTION},
|
|
238
|
+
{"generate", KEYWORD_GENERATE},
|
|
239
|
+
{"generic", KEYWORD_GENERIC},
|
|
240
|
+
{"group", KEYWORD_GROUP},
|
|
241
|
+
{"guarded", KEYWORD_GUARDED},
|
|
242
|
+
{"if", KEYWORD_IF},
|
|
243
|
+
{"impure", KEYWORD_IMPURE},
|
|
244
|
+
{"in", KEYWORD_IN},
|
|
245
|
+
{"inertial", KEYWORD_INERTIAL},
|
|
246
|
+
{"inout", KEYWORD_INOUT},
|
|
247
|
+
{"is", KEYWORD_IS},
|
|
248
|
+
{"label", KEYWORD_LABEL},
|
|
249
|
+
{"library", KEYWORD_LIBRARY},
|
|
250
|
+
{"linkage", KEYWORD_LINKAGE},
|
|
251
|
+
{"literal", KEYWORD_LITERAL},
|
|
252
|
+
{"loop", KEYWORD_LOOP},
|
|
253
|
+
{"map", KEYWORD_MAP},
|
|
254
|
+
{"mod", KEYWORD_MOD},
|
|
255
|
+
{"nand", KEYWORD_NAND},
|
|
256
|
+
{"new", KEYWORD_NEW},
|
|
257
|
+
{"next", KEYWORD_NEXT},
|
|
258
|
+
{"nor", KEYWORD_NOR},
|
|
259
|
+
{"not", KEYWORD_NOT},
|
|
260
|
+
{"null", KEYWORD_NULL},
|
|
261
|
+
{"of", KEYWORD_OF},
|
|
262
|
+
{"on", KEYWORD_ON},
|
|
263
|
+
{"open", KEYWORD_OPEN},
|
|
264
|
+
{"or", KEYWORD_OR},
|
|
265
|
+
{"others", KEYWORD_OTHERS},
|
|
266
|
+
{"out", KEYWORD_OUT},
|
|
267
|
+
{"package", KEYWORD_PACKAGE},
|
|
268
|
+
{"port", KEYWORD_PORT},
|
|
269
|
+
{"postponed", KEYWORD_POSTPONED},
|
|
270
|
+
{"procedure", KEYWORD_PROCEDURE},
|
|
271
|
+
{"process", KEYWORD_PROCESS},
|
|
272
|
+
{"pure", KEYWORD_PURE},
|
|
273
|
+
{"range", KEYWORD_RANGE},
|
|
274
|
+
{"record", KEYWORD_RECORD},
|
|
275
|
+
{"register", KEYWORD_REGISTER},
|
|
276
|
+
{"reject", KEYWORD_REJECT},
|
|
277
|
+
{"return", KEYWORD_RETURN},
|
|
278
|
+
{"rol", KEYWORD_ROL},
|
|
279
|
+
{"ror", KEYWORD_ROR},
|
|
280
|
+
{"select", KEYWORD_SELECT},
|
|
281
|
+
{"severity", KEYWORD_SEVERITY},
|
|
282
|
+
{"signal", KEYWORD_SIGNAL},
|
|
283
|
+
{"shared", KEYWORD_SHARED},
|
|
284
|
+
{"sla", KEYWORD_SLA},
|
|
285
|
+
{"sli", KEYWORD_SLI},
|
|
286
|
+
{"sra", KEYWORD_SRA},
|
|
287
|
+
{"srl", KEYWORD_SRL},
|
|
288
|
+
{"subtype", KEYWORD_SUBTYPE},
|
|
289
|
+
{"then", KEYWORD_THEN},
|
|
290
|
+
{"to", KEYWORD_TO},
|
|
291
|
+
{"transport", KEYWORD_TRANSPORT},
|
|
292
|
+
{"type", KEYWORD_TYPE},
|
|
293
|
+
{"unaffected", KEYWORD_UNAFFECTED},
|
|
294
|
+
{"units", KEYWORD_UNITS},
|
|
295
|
+
{"until", KEYWORD_UNTIL},
|
|
296
|
+
{"use", KEYWORD_USE},
|
|
297
|
+
{"variable", KEYWORD_VARIABLE},
|
|
298
|
+
{"wait", KEYWORD_WAIT},
|
|
299
|
+
{"when", KEYWORD_WHEN},
|
|
300
|
+
{"while", KEYWORD_WHILE},
|
|
301
|
+
{"with", KEYWORD_WITH},
|
|
302
|
+
{"xnor", KEYWORD_XNOR},
|
|
303
|
+
{"xor", KEYWORD_XOR}
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
/*
|
|
307
|
+
* FUNCTION DECLARATIONS
|
|
308
|
+
*/
|
|
309
|
+
static void parseKeywords (tokenInfo * const token, boolean local);
|
|
310
|
+
|
|
311
|
+
/*
|
|
312
|
+
* FUNCTION DEFINITIONS
|
|
313
|
+
*/
|
|
314
|
+
|
|
315
|
+
static boolean isIdentChar1 (const int c)
|
|
316
|
+
{
|
|
317
|
+
return (boolean) (isalpha (c) || c == '_');
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
static boolean isIdentChar (const int c)
|
|
321
|
+
{
|
|
322
|
+
return (boolean) (isalpha (c) || isdigit (c) || c == '_');
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
static boolean isIdentifierMatch (const tokenInfo * const token,
|
|
326
|
+
const vString * const name)
|
|
327
|
+
{
|
|
328
|
+
return (boolean) (isType (token, TOKEN_IDENTIFIER) &&
|
|
329
|
+
strcasecmp (vStringValue (token->string), vStringValue (name)) == 0);
|
|
330
|
+
/* XXX this is copy/paste from eiffel.c and slightly modified */
|
|
331
|
+
/* shouldn't we use strNcasecmp ? */
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
static boolean isKeywordOrIdent (const tokenInfo * const token,
|
|
335
|
+
const keywordId keyword, const vString * const name)
|
|
336
|
+
{
|
|
337
|
+
return (boolean) (isKeyword (token, keyword) ||
|
|
338
|
+
isIdentifierMatch (token, name));
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
static tokenInfo *newToken (void)
|
|
342
|
+
{
|
|
343
|
+
tokenInfo *const token = xMalloc (1, tokenInfo);
|
|
344
|
+
token->type = TOKEN_NONE;
|
|
345
|
+
token->keyword = KEYWORD_NONE;
|
|
346
|
+
token->string = vStringNew ();
|
|
347
|
+
token->scope = vStringNew ();
|
|
348
|
+
token->lineNumber = getSourceLineNumber ();
|
|
349
|
+
token->filePosition = getInputFilePosition ();
|
|
350
|
+
return token;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
static void deleteToken (tokenInfo * const token)
|
|
354
|
+
{
|
|
355
|
+
if (token != NULL)
|
|
356
|
+
{
|
|
357
|
+
vStringDelete (token->string);
|
|
358
|
+
vStringDelete (token->scope);
|
|
359
|
+
eFree (token);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/*
|
|
364
|
+
* Parsing functions
|
|
365
|
+
*/
|
|
366
|
+
|
|
367
|
+
static void parseString (vString * const string, const int delimiter)
|
|
368
|
+
{
|
|
369
|
+
boolean end = FALSE;
|
|
370
|
+
while (!end)
|
|
371
|
+
{
|
|
372
|
+
int c = fileGetc ();
|
|
373
|
+
if (c == EOF)
|
|
374
|
+
end = TRUE;
|
|
375
|
+
else if (c == '\\')
|
|
376
|
+
{
|
|
377
|
+
c = fileGetc (); /* This maybe a ' or ". */
|
|
378
|
+
vStringPut (string, c);
|
|
379
|
+
}
|
|
380
|
+
else if (c == delimiter)
|
|
381
|
+
end = TRUE;
|
|
382
|
+
else
|
|
383
|
+
vStringPut (string, c);
|
|
384
|
+
}
|
|
385
|
+
vStringTerminate (string);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/* Read a VHDL identifier beginning with "firstChar" and place it into "name".
|
|
389
|
+
*/
|
|
390
|
+
static void parseIdentifier (vString * const string, const int firstChar)
|
|
391
|
+
{
|
|
392
|
+
int c = firstChar;
|
|
393
|
+
Assert (isIdentChar1 (c));
|
|
394
|
+
do
|
|
395
|
+
{
|
|
396
|
+
vStringPut (string, c);
|
|
397
|
+
c = fileGetc ();
|
|
398
|
+
} while (isIdentChar (c));
|
|
399
|
+
vStringTerminate (string);
|
|
400
|
+
if (!isspace (c))
|
|
401
|
+
fileUngetc (c); /* unget non-identifier character */
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
static void readToken (tokenInfo * const token)
|
|
405
|
+
{
|
|
406
|
+
int c;
|
|
407
|
+
|
|
408
|
+
token->type = TOKEN_NONE;
|
|
409
|
+
token->keyword = KEYWORD_NONE;
|
|
410
|
+
vStringClear (token->string);
|
|
411
|
+
|
|
412
|
+
getNextChar:
|
|
413
|
+
do
|
|
414
|
+
{
|
|
415
|
+
c = fileGetc ();
|
|
416
|
+
token->lineNumber = getSourceLineNumber ();
|
|
417
|
+
token->filePosition = getInputFilePosition ();
|
|
418
|
+
}
|
|
419
|
+
while (c == '\t' || c == ' ' || c == '\n');
|
|
420
|
+
|
|
421
|
+
switch (c)
|
|
422
|
+
{
|
|
423
|
+
case EOF:
|
|
424
|
+
longjmp (Exception, (int) ExceptionEOF);
|
|
425
|
+
break;
|
|
426
|
+
case '(':
|
|
427
|
+
token->type = TOKEN_OPEN_PAREN;
|
|
428
|
+
break;
|
|
429
|
+
case ')':
|
|
430
|
+
token->type = TOKEN_CLOSE_PAREN;
|
|
431
|
+
break;
|
|
432
|
+
case ';':
|
|
433
|
+
token->type = TOKEN_SEMICOLON;
|
|
434
|
+
break;
|
|
435
|
+
case '.':
|
|
436
|
+
token->type = TOKEN_PERIOD;
|
|
437
|
+
break;
|
|
438
|
+
case ',':
|
|
439
|
+
token->type = TOKEN_COMMA;
|
|
440
|
+
break;
|
|
441
|
+
case '\'': /* only single char are inside simple quotes */
|
|
442
|
+
break; /* or it is for attributes so we don't care */
|
|
443
|
+
case '"':
|
|
444
|
+
token->type = TOKEN_STRING;
|
|
445
|
+
parseString (token->string, c);
|
|
446
|
+
token->lineNumber = getSourceLineNumber ();
|
|
447
|
+
token->filePosition = getInputFilePosition ();
|
|
448
|
+
break;
|
|
449
|
+
case '-':
|
|
450
|
+
c = fileGetc ();
|
|
451
|
+
if (c == '-') /* start of a comment */
|
|
452
|
+
{
|
|
453
|
+
fileSkipToCharacter ('\n');
|
|
454
|
+
goto getNextChar;
|
|
455
|
+
}
|
|
456
|
+
else
|
|
457
|
+
{
|
|
458
|
+
if (!isspace (c))
|
|
459
|
+
fileUngetc (c);
|
|
460
|
+
token->type = TOKEN_OPERATOR;
|
|
461
|
+
}
|
|
462
|
+
break;
|
|
463
|
+
default:
|
|
464
|
+
if (!isIdentChar1 (c))
|
|
465
|
+
token->type = TOKEN_NONE;
|
|
466
|
+
else
|
|
467
|
+
{
|
|
468
|
+
parseIdentifier (token->string, c);
|
|
469
|
+
token->lineNumber = getSourceLineNumber ();
|
|
470
|
+
token->filePosition = getInputFilePosition ();
|
|
471
|
+
token->keyword = analyzeToken (token->string, Lang_vhdl);
|
|
472
|
+
if (isKeyword (token, KEYWORD_NONE))
|
|
473
|
+
token->type = TOKEN_IDENTIFIER;
|
|
474
|
+
else
|
|
475
|
+
token->type = TOKEN_KEYWORD;
|
|
476
|
+
}
|
|
477
|
+
break;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
static void skipToKeyword (const keywordId keyword)
|
|
482
|
+
{
|
|
483
|
+
tokenInfo *const token = newToken ();
|
|
484
|
+
do
|
|
485
|
+
{
|
|
486
|
+
readToken (token);
|
|
487
|
+
}
|
|
488
|
+
while (!isKeyword (token, keyword));
|
|
489
|
+
deleteToken (token);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
static void skipToMatched (tokenInfo * const token)
|
|
493
|
+
{
|
|
494
|
+
int nest_level = 0;
|
|
495
|
+
tokenType open_token;
|
|
496
|
+
tokenType close_token;
|
|
497
|
+
|
|
498
|
+
switch (token->type)
|
|
499
|
+
{
|
|
500
|
+
case TOKEN_OPEN_PAREN:
|
|
501
|
+
open_token = TOKEN_OPEN_PAREN;
|
|
502
|
+
close_token = TOKEN_CLOSE_PAREN;
|
|
503
|
+
break;
|
|
504
|
+
default:
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/*
|
|
509
|
+
* This routine will skip to a matching closing token.
|
|
510
|
+
* It will also handle nested tokens like the (, ) below.
|
|
511
|
+
* ( name varchar(30), text binary(10) )
|
|
512
|
+
*/
|
|
513
|
+
if (isType (token, open_token))
|
|
514
|
+
{
|
|
515
|
+
nest_level++;
|
|
516
|
+
while (!(isType (token, close_token) && (nest_level == 0)))
|
|
517
|
+
{
|
|
518
|
+
readToken (token);
|
|
519
|
+
if (isType (token, open_token))
|
|
520
|
+
{
|
|
521
|
+
nest_level++;
|
|
522
|
+
}
|
|
523
|
+
if (isType (token, close_token))
|
|
524
|
+
{
|
|
525
|
+
if (nest_level > 0)
|
|
526
|
+
{
|
|
527
|
+
nest_level--;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
readToken (token);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
static void makeConstTag (tokenInfo * const token, const vhdlKind kind)
|
|
536
|
+
{
|
|
537
|
+
if (VhdlKinds[kind].enabled)
|
|
538
|
+
{
|
|
539
|
+
const char *const name = vStringValue (token->string);
|
|
540
|
+
tagEntryInfo e;
|
|
541
|
+
initTagEntry (&e, name);
|
|
542
|
+
e.lineNumber = token->lineNumber;
|
|
543
|
+
e.filePosition = token->filePosition;
|
|
544
|
+
e.kindName = VhdlKinds[kind].name;
|
|
545
|
+
e.kind = VhdlKinds[kind].letter;
|
|
546
|
+
makeTagEntry (&e);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
static void makeVhdlTag (tokenInfo * const token, const vhdlKind kind)
|
|
551
|
+
{
|
|
552
|
+
if (VhdlKinds[kind].enabled)
|
|
553
|
+
{
|
|
554
|
+
/*
|
|
555
|
+
* If a scope has been added to the token, change the token
|
|
556
|
+
* string to include the scope when making the tag.
|
|
557
|
+
*/
|
|
558
|
+
if (vStringLength (token->scope) > 0)
|
|
559
|
+
{
|
|
560
|
+
vString *fulltag = vStringNew ();
|
|
561
|
+
vStringCopy (fulltag, token->scope);
|
|
562
|
+
vStringCatS (fulltag, ".");
|
|
563
|
+
vStringCatS (fulltag, vStringValue (token->string));
|
|
564
|
+
vStringTerminate (fulltag);
|
|
565
|
+
vStringCopy (token->string, fulltag);
|
|
566
|
+
vStringDelete (fulltag);
|
|
567
|
+
}
|
|
568
|
+
makeConstTag (token, kind);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
static void initialize (const langType language)
|
|
573
|
+
{
|
|
574
|
+
size_t i;
|
|
575
|
+
const size_t count =
|
|
576
|
+
sizeof (VhdlKeywordTable) / sizeof (VhdlKeywordTable[0]);
|
|
577
|
+
Lang_vhdl = language;
|
|
578
|
+
for (i = 0; i < count; ++i)
|
|
579
|
+
{
|
|
580
|
+
const keywordDesc *const p = &VhdlKeywordTable[i];
|
|
581
|
+
addKeyword (p->name, language, (int) p->id);
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
static void parsePackage (tokenInfo * const token)
|
|
586
|
+
{
|
|
587
|
+
tokenInfo *const name = newToken ();
|
|
588
|
+
Assert (isKeyword (token, KEYWORD_PACKAGE));
|
|
589
|
+
readToken (token);
|
|
590
|
+
if (isKeyword (token, KEYWORD_BODY))
|
|
591
|
+
{
|
|
592
|
+
readToken (name);
|
|
593
|
+
makeVhdlTag (name, VHDLTAG_PACKAGE);
|
|
594
|
+
}
|
|
595
|
+
else if (isType (token, TOKEN_IDENTIFIER))
|
|
596
|
+
{
|
|
597
|
+
makeVhdlTag (token, VHDLTAG_PACKAGE);
|
|
598
|
+
}
|
|
599
|
+
deleteToken (name);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
static void parseModule (tokenInfo * const token)
|
|
603
|
+
{
|
|
604
|
+
tokenInfo *const name = newToken ();
|
|
605
|
+
const vhdlKind kind = isKeyword (token, KEYWORD_ENTITY) ?
|
|
606
|
+
VHDLTAG_ENTITY : VHDLTAG_COMPONENT;
|
|
607
|
+
Assert (isKeyword (token, KEYWORD_ENTITY) ||
|
|
608
|
+
isKeyword (token, KEYWORD_COMPONENT));
|
|
609
|
+
readToken (name);
|
|
610
|
+
if (kind == VHDLTAG_COMPONENT)
|
|
611
|
+
{
|
|
612
|
+
makeVhdlTag (name, VHDLTAG_COMPONENT);
|
|
613
|
+
skipToKeyword (KEYWORD_END);
|
|
614
|
+
fileSkipToCharacter (';');
|
|
615
|
+
}
|
|
616
|
+
else
|
|
617
|
+
{
|
|
618
|
+
readToken (token);
|
|
619
|
+
if (isKeyword (token, KEYWORD_IS))
|
|
620
|
+
{
|
|
621
|
+
makeVhdlTag (name, VHDLTAG_ENTITY);
|
|
622
|
+
skipToKeyword (KEYWORD_END);
|
|
623
|
+
fileSkipToCharacter (';');
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
deleteToken (name);
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
static void parseRecord (tokenInfo * const token)
|
|
630
|
+
{
|
|
631
|
+
tokenInfo *const name = newToken ();
|
|
632
|
+
Assert (isKeyword (token, KEYWORD_RECORD));
|
|
633
|
+
readToken (name);
|
|
634
|
+
do
|
|
635
|
+
{
|
|
636
|
+
readToken (token); /* should be a colon */
|
|
637
|
+
fileSkipToCharacter (';');
|
|
638
|
+
makeVhdlTag (name, VHDLTAG_RECORD);
|
|
639
|
+
readToken (name);
|
|
640
|
+
}
|
|
641
|
+
while (!isKeyword (name, KEYWORD_END));
|
|
642
|
+
fileSkipToCharacter (';');
|
|
643
|
+
deleteToken (name);
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
static void parseTypes (tokenInfo * const token)
|
|
647
|
+
{
|
|
648
|
+
tokenInfo *const name = newToken ();
|
|
649
|
+
const vhdlKind kind = isKeyword (token, KEYWORD_TYPE) ?
|
|
650
|
+
VHDLTAG_TYPE : VHDLTAG_SUBTYPE;
|
|
651
|
+
Assert (isKeyword (token, KEYWORD_TYPE) ||
|
|
652
|
+
isKeyword (token, KEYWORD_SUBTYPE));
|
|
653
|
+
readToken (name);
|
|
654
|
+
readToken (token);
|
|
655
|
+
if (isKeyword (token, KEYWORD_IS))
|
|
656
|
+
{
|
|
657
|
+
readToken (token); /* type */
|
|
658
|
+
if (isKeyword (token, KEYWORD_RECORD))
|
|
659
|
+
{
|
|
660
|
+
makeVhdlTag (name, kind);
|
|
661
|
+
/*TODO: make tags of the record's names */
|
|
662
|
+
parseRecord (token);
|
|
663
|
+
}
|
|
664
|
+
else
|
|
665
|
+
{
|
|
666
|
+
makeVhdlTag (name, kind);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
deleteToken (name);
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
static void parseConstant (boolean local)
|
|
673
|
+
{
|
|
674
|
+
tokenInfo *const name = newToken ();
|
|
675
|
+
readToken (name);
|
|
676
|
+
if (local)
|
|
677
|
+
{
|
|
678
|
+
makeVhdlTag (name, VHDLTAG_LOCAL);
|
|
679
|
+
}
|
|
680
|
+
else
|
|
681
|
+
{
|
|
682
|
+
makeVhdlTag (name, VHDLTAG_CONSTANT);
|
|
683
|
+
}
|
|
684
|
+
fileSkipToCharacter (';');
|
|
685
|
+
deleteToken (name);
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
static void parseSubProgram (tokenInfo * const token)
|
|
689
|
+
{
|
|
690
|
+
tokenInfo *const name = newToken ();
|
|
691
|
+
boolean endSubProgram = FALSE;
|
|
692
|
+
const vhdlKind kind = isKeyword (token, KEYWORD_FUNCTION) ?
|
|
693
|
+
VHDLTAG_FUNCTION : VHDLTAG_PROCEDURE;
|
|
694
|
+
Assert (isKeyword (token, KEYWORD_FUNCTION) ||
|
|
695
|
+
isKeyword (token, KEYWORD_PROCEDURE));
|
|
696
|
+
readToken (name); /* the name of the function or procedure */
|
|
697
|
+
readToken (token);
|
|
698
|
+
if (isType (token, TOKEN_OPEN_PAREN))
|
|
699
|
+
{
|
|
700
|
+
skipToMatched (token);
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
if (kind == VHDLTAG_FUNCTION)
|
|
704
|
+
{
|
|
705
|
+
if (isKeyword (token, KEYWORD_RETURN))
|
|
706
|
+
{
|
|
707
|
+
/* Read datatype */
|
|
708
|
+
readToken (token);
|
|
709
|
+
while (! isKeyword (token, KEYWORD_IS) &&
|
|
710
|
+
! isType (token, TOKEN_SEMICOLON))
|
|
711
|
+
{
|
|
712
|
+
readToken (token);
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
if (isType (token, TOKEN_SEMICOLON))
|
|
718
|
+
{
|
|
719
|
+
makeVhdlTag (name, VHDLTAG_PROTOTYPE);
|
|
720
|
+
}
|
|
721
|
+
else if (isKeyword (token, KEYWORD_IS))
|
|
722
|
+
{
|
|
723
|
+
if (kind == VHDLTAG_FUNCTION)
|
|
724
|
+
{
|
|
725
|
+
makeVhdlTag (name, VHDLTAG_FUNCTION);
|
|
726
|
+
do
|
|
727
|
+
{
|
|
728
|
+
readToken (token);
|
|
729
|
+
if (isKeyword (token, KEYWORD_END))
|
|
730
|
+
{
|
|
731
|
+
readToken (token);
|
|
732
|
+
endSubProgram = isKeywordOrIdent (token,
|
|
733
|
+
KEYWORD_FUNCTION, name->string);
|
|
734
|
+
fileSkipToCharacter (';');
|
|
735
|
+
}
|
|
736
|
+
else
|
|
737
|
+
{
|
|
738
|
+
parseKeywords (token, TRUE);
|
|
739
|
+
}
|
|
740
|
+
} while (!endSubProgram);
|
|
741
|
+
}
|
|
742
|
+
else
|
|
743
|
+
{
|
|
744
|
+
makeVhdlTag (name, VHDLTAG_PROCEDURE);
|
|
745
|
+
do
|
|
746
|
+
{
|
|
747
|
+
readToken (token);
|
|
748
|
+
if (isKeyword (token, KEYWORD_END))
|
|
749
|
+
{
|
|
750
|
+
readToken (token);
|
|
751
|
+
endSubProgram = isKeywordOrIdent (token,
|
|
752
|
+
KEYWORD_PROCEDURE, name->string);
|
|
753
|
+
fileSkipToCharacter (';');
|
|
754
|
+
}
|
|
755
|
+
else
|
|
756
|
+
{
|
|
757
|
+
parseKeywords (token, TRUE);
|
|
758
|
+
}
|
|
759
|
+
} while (!endSubProgram);
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
deleteToken (name);
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
/* TODO */
|
|
766
|
+
/* records */
|
|
767
|
+
static void parseKeywords (tokenInfo * const token, boolean local)
|
|
768
|
+
{
|
|
769
|
+
switch (token->keyword)
|
|
770
|
+
{
|
|
771
|
+
case KEYWORD_END:
|
|
772
|
+
fileSkipToCharacter (';');
|
|
773
|
+
break;
|
|
774
|
+
case KEYWORD_CONSTANT:
|
|
775
|
+
parseConstant (local);
|
|
776
|
+
break;
|
|
777
|
+
case KEYWORD_TYPE:
|
|
778
|
+
parseTypes (token);
|
|
779
|
+
break;
|
|
780
|
+
case KEYWORD_SUBTYPE:
|
|
781
|
+
parseTypes (token);
|
|
782
|
+
break;
|
|
783
|
+
case KEYWORD_ENTITY:
|
|
784
|
+
parseModule (token);
|
|
785
|
+
break;
|
|
786
|
+
case KEYWORD_COMPONENT:
|
|
787
|
+
parseModule (token);
|
|
788
|
+
break;
|
|
789
|
+
case KEYWORD_FUNCTION:
|
|
790
|
+
parseSubProgram (token);
|
|
791
|
+
break;
|
|
792
|
+
case KEYWORD_PROCEDURE:
|
|
793
|
+
parseSubProgram (token);
|
|
794
|
+
break;
|
|
795
|
+
case KEYWORD_PACKAGE:
|
|
796
|
+
parsePackage (token);
|
|
797
|
+
break;
|
|
798
|
+
default:
|
|
799
|
+
break;
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
static void parseVhdlFile (tokenInfo * const token)
|
|
804
|
+
{
|
|
805
|
+
do
|
|
806
|
+
{
|
|
807
|
+
readToken (token);
|
|
808
|
+
parseKeywords (token, FALSE);
|
|
809
|
+
} while (!isKeyword (token, KEYWORD_END));
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
static void findVhdlTags (void)
|
|
813
|
+
{
|
|
814
|
+
tokenInfo *const token = newToken ();
|
|
815
|
+
exception_t exception = (exception_t) (setjmp (Exception));
|
|
816
|
+
|
|
817
|
+
while (exception == ExceptionNone)
|
|
818
|
+
parseVhdlFile (token);
|
|
819
|
+
|
|
820
|
+
deleteToken (token);
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
extern parserDefinition *VhdlParser (void)
|
|
824
|
+
{
|
|
825
|
+
static const char *const extensions[] = { "vhdl", "vhd", NULL };
|
|
826
|
+
parserDefinition *def = parserNew ("VHDL");
|
|
827
|
+
def->kinds = VhdlKinds;
|
|
828
|
+
def->kindCount = KIND_COUNT (VhdlKinds);
|
|
829
|
+
def->extensions = extensions;
|
|
830
|
+
def->parser = findVhdlTags;
|
|
831
|
+
def->initialize = initialize;
|
|
832
|
+
return def;
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
/* vi:set tabstop=4 shiftwidth=4 noet: */
|