xref: /Universal-ctags/parsers/vhdl.c (revision aaaac7eeac8399141aa8e6d9e6ec0379931848b2)
13ae02089SMasatake YAMATO /*
23ae02089SMasatake YAMATO *   Copyright (c) 2008, Nicolas Vincent
33ae02089SMasatake YAMATO *
43ae02089SMasatake YAMATO *   This source code is released for free distribution under the terms of the
50ce38835Sviccuad *   GNU General Public License version 2 or (at your option) any later version.
63ae02089SMasatake YAMATO *
73ae02089SMasatake YAMATO *   This module contains functions for generating tags for VHDL files.
80002e478SMasatake YAMATO *
90002e478SMasatake YAMATO *   References:
10475e2509SMasatake YAMATO *     https://rti.etf.bg.ac.rs/rti/ri5rvl/tutorial/TUTORIAL/IEEE/HTML/1076_TOC.HTM
11475e2509SMasatake YAMATO *     https://tams.informatik.uni-hamburg.de/vhdl/tools/grammar/vhdl93-bnf.html
120002e478SMasatake YAMATO *     http://www.vhdl.renerta.com/mobile/index.html
130002e478SMasatake YAMATO *     https://www.hdlworks.com/hdl_corner/vhdl_ref/
140002e478SMasatake YAMATO *     https://www.ics.uci.edu/~jmoorkan/vhdlref/Synario%20VHDL%20Manual.pdf
150002e478SMasatake YAMATO *     http://atlas.physics.arizona.edu/~kjohns/downloads/vhdl/VHDL-xilinx-help.pdf
160002e478SMasatake YAMATO *     http://www.csit-sun.pub.ro/resources/xilinx/synvhdl.pdf
170002e478SMasatake YAMATO *     https://edg.uchicago.edu/~tang/VHDLref.pdf
183ae02089SMasatake YAMATO */
193ae02089SMasatake YAMATO 
203ae02089SMasatake YAMATO /*
213ae02089SMasatake YAMATO  *   INCLUDE FILES
223ae02089SMasatake YAMATO  */
233ae02089SMasatake YAMATO #include "general.h"	/* must always come first */
243ae02089SMasatake YAMATO 
253ae02089SMasatake YAMATO #include <ctype.h>	/* to define isalpha () */
263ae02089SMasatake YAMATO #include <string.h>
273ae02089SMasatake YAMATO 
283ae02089SMasatake YAMATO #include "debug.h"
293ae02089SMasatake YAMATO #include "entry.h"
303ae02089SMasatake YAMATO #include "keyword.h"
313ae02089SMasatake YAMATO #include "parse.h"
323ae02089SMasatake YAMATO #include "read.h"
333ae02089SMasatake YAMATO #include "routines.h"
343ae02089SMasatake YAMATO #include "vstring.h"
350b86d0e9SMasatake YAMATO #include "trace.h"
363ae02089SMasatake YAMATO 
373ae02089SMasatake YAMATO /*
383ae02089SMasatake YAMATO  *   MACROS
393ae02089SMasatake YAMATO  */
40ce990805SThomas Braun #define isType(token,t)     (bool) ((token)->type == (t))
41ce990805SThomas Braun #define isKeyword(token,k)  (bool) ((token)->keyword == (k))
422b28d0e0SJiří Techet #define isIdentChar1(c) (isalpha (c) || (c) == '_')
432b28d0e0SJiří Techet #define isIdentChar(c) (isalpha (c) || isdigit (c) || (c) == '_')
443ae02089SMasatake YAMATO 
453ae02089SMasatake YAMATO /*
463ae02089SMasatake YAMATO  *   DATA DECLARATIONS
473ae02089SMasatake YAMATO  */
483ae02089SMasatake YAMATO 
493ae02089SMasatake YAMATO /*
503ae02089SMasatake YAMATO  * Used to specify type of keyword.
513ae02089SMasatake YAMATO  */
524faa2076SColomban Wendling enum eKeywordId {
533ae02089SMasatake YAMATO 	KEYWORD_ABS,
543ae02089SMasatake YAMATO 	KEYWORD_ACCESS,
553ae02089SMasatake YAMATO 	KEYWORD_AFTER,
563ae02089SMasatake YAMATO 	KEYWORD_ALIAS,
573ae02089SMasatake YAMATO 	KEYWORD_ALL,
583ae02089SMasatake YAMATO 	KEYWORD_AND,
593ae02089SMasatake YAMATO 	KEYWORD_ARCHITECTURE,
603ae02089SMasatake YAMATO 	KEYWORD_ARRAY,
613ae02089SMasatake YAMATO 	KEYWORD_ASSERT,
623ae02089SMasatake YAMATO 	KEYWORD_ATTRIBUTE,
633ae02089SMasatake YAMATO 	KEYWORD_BEGIN,
643ae02089SMasatake YAMATO 	KEYWORD_BLOCK,
653ae02089SMasatake YAMATO 	KEYWORD_BODY,
663ae02089SMasatake YAMATO 	KEYWORD_BUFFER,
673ae02089SMasatake YAMATO 	KEYWORD_BUS,
683ae02089SMasatake YAMATO 	KEYWORD_CASE,
693ae02089SMasatake YAMATO 	KEYWORD_COMPONENT,
703ae02089SMasatake YAMATO 	KEYWORD_CONFIGURATION,
713ae02089SMasatake YAMATO 	KEYWORD_CONSTANT,
723ae02089SMasatake YAMATO 	KEYWORD_DISCONNECT,
733ae02089SMasatake YAMATO 	KEYWORD_DOWNTO,
743ae02089SMasatake YAMATO 	KEYWORD_ELSE,
753ae02089SMasatake YAMATO 	KEYWORD_ELSIF,
763ae02089SMasatake YAMATO 	KEYWORD_END,
773ae02089SMasatake YAMATO 	KEYWORD_ENTITY,
783ae02089SMasatake YAMATO 	KEYWORD_EXIT,
793ae02089SMasatake YAMATO 	KEYWORD_FILE,
803ae02089SMasatake YAMATO 	KEYWORD_FOR,
813ae02089SMasatake YAMATO 	KEYWORD_FUNCTION,
823ae02089SMasatake YAMATO 	KEYWORD_GENERATE,
833ae02089SMasatake YAMATO 	KEYWORD_GENERIC,
843ae02089SMasatake YAMATO 	KEYWORD_GROUP,
853ae02089SMasatake YAMATO 	KEYWORD_GUARDED,
863ae02089SMasatake YAMATO 	KEYWORD_IF,
873ae02089SMasatake YAMATO 	KEYWORD_IMPURE,
883ae02089SMasatake YAMATO 	KEYWORD_IN,
893ae02089SMasatake YAMATO 	KEYWORD_INERTIAL,
903ae02089SMasatake YAMATO 	KEYWORD_INOUT,
913ae02089SMasatake YAMATO 	KEYWORD_IS,
923ae02089SMasatake YAMATO 	KEYWORD_LABEL,
933ae02089SMasatake YAMATO 	KEYWORD_LIBRARY,
943ae02089SMasatake YAMATO 	KEYWORD_LINKAGE,
953ae02089SMasatake YAMATO 	KEYWORD_LITERAL,
963ae02089SMasatake YAMATO 	KEYWORD_LOOP,
973ae02089SMasatake YAMATO 	KEYWORD_MAP,
983ae02089SMasatake YAMATO 	KEYWORD_MOD,
993ae02089SMasatake YAMATO 	KEYWORD_NAND,
1003ae02089SMasatake YAMATO 	KEYWORD_NEW,
1013ae02089SMasatake YAMATO 	KEYWORD_NEXT,
1023ae02089SMasatake YAMATO 	KEYWORD_NOR,
1033ae02089SMasatake YAMATO 	KEYWORD_NOT,
1043ae02089SMasatake YAMATO 	KEYWORD_NULL,
1053ae02089SMasatake YAMATO 	KEYWORD_OF,
1063ae02089SMasatake YAMATO 	KEYWORD_ON,
1073ae02089SMasatake YAMATO 	KEYWORD_OPEN,
1083ae02089SMasatake YAMATO 	KEYWORD_OR,
1093ae02089SMasatake YAMATO 	KEYWORD_OTHERS,
1103ae02089SMasatake YAMATO 	KEYWORD_OUT,
1113ae02089SMasatake YAMATO 	KEYWORD_PACKAGE,
1123ae02089SMasatake YAMATO 	KEYWORD_PORT,
1133ae02089SMasatake YAMATO 	KEYWORD_POSTPONED,
1143ae02089SMasatake YAMATO 	KEYWORD_PROCEDURE,
1153ae02089SMasatake YAMATO 	KEYWORD_PROCESS,
1163ae02089SMasatake YAMATO 	KEYWORD_PURE,
1173ae02089SMasatake YAMATO 	KEYWORD_RANGE,
1183ae02089SMasatake YAMATO 	KEYWORD_RECORD,
1193ae02089SMasatake YAMATO 	KEYWORD_REGISTER,
1203ae02089SMasatake YAMATO 	KEYWORD_REJECT,
1213ae02089SMasatake YAMATO 	KEYWORD_RETURN,
1223ae02089SMasatake YAMATO 	KEYWORD_ROL,
1233ae02089SMasatake YAMATO 	KEYWORD_ROR,
1243ae02089SMasatake YAMATO 	KEYWORD_SELECT,
1253ae02089SMasatake YAMATO 	KEYWORD_SEVERITY,
1263ae02089SMasatake YAMATO 	KEYWORD_SIGNAL,
1273ae02089SMasatake YAMATO 	KEYWORD_SHARED,
1283ae02089SMasatake YAMATO 	KEYWORD_SLA,
1293ae02089SMasatake YAMATO 	KEYWORD_SLI,
1303ae02089SMasatake YAMATO 	KEYWORD_SRA,
1313ae02089SMasatake YAMATO 	KEYWORD_SRL,
1323ae02089SMasatake YAMATO 	KEYWORD_SUBTYPE,
1333ae02089SMasatake YAMATO 	KEYWORD_THEN,
1343ae02089SMasatake YAMATO 	KEYWORD_TO,
1353ae02089SMasatake YAMATO 	KEYWORD_TRANSPORT,
1363ae02089SMasatake YAMATO 	KEYWORD_TYPE,
1373ae02089SMasatake YAMATO 	KEYWORD_UNAFFECTED,
1383ae02089SMasatake YAMATO 	KEYWORD_UNITS,
1393ae02089SMasatake YAMATO 	KEYWORD_UNTIL,
1403ae02089SMasatake YAMATO 	KEYWORD_USE,
1413ae02089SMasatake YAMATO 	KEYWORD_VARIABLE,
1423ae02089SMasatake YAMATO 	KEYWORD_WAIT,
1433ae02089SMasatake YAMATO 	KEYWORD_WHEN,
1443ae02089SMasatake YAMATO 	KEYWORD_WHILE,
1453ae02089SMasatake YAMATO 	KEYWORD_WITH,
1463ae02089SMasatake YAMATO 	KEYWORD_XNOR,
1473ae02089SMasatake YAMATO 	KEYWORD_XOR
1484faa2076SColomban Wendling };
1494faa2076SColomban Wendling typedef int keywordId; /* to allow KEYWORD_NONE */
1503ae02089SMasatake YAMATO 
1513ae02089SMasatake YAMATO typedef enum eTokenType {
1523ae02089SMasatake YAMATO 	TOKEN_NONE,		/* none */
1533ae02089SMasatake YAMATO 	TOKEN_EOF,		/* end-of-file */
1543ae02089SMasatake YAMATO 	TOKEN_OPEN_PAREN,	/* ( */
1553ae02089SMasatake YAMATO 	TOKEN_CLOSE_PAREN,	/* ) */
1563ae02089SMasatake YAMATO 	TOKEN_COMMA,		/* the comma character */
1573ae02089SMasatake YAMATO 	TOKEN_IDENTIFIER,
1583ae02089SMasatake YAMATO 	TOKEN_KEYWORD,
1593ae02089SMasatake YAMATO 	TOKEN_PERIOD,		/* . */
1603ae02089SMasatake YAMATO 	TOKEN_OPERATOR,
1613ae02089SMasatake YAMATO 	TOKEN_SEMICOLON,	/* the semicolon character */
1620b86d0e9SMasatake YAMATO 	TOKEN_COLON,		/* : */
1633ae02089SMasatake YAMATO 	TOKEN_STRING
1643ae02089SMasatake YAMATO } tokenType;
1653ae02089SMasatake YAMATO 
1663ae02089SMasatake YAMATO typedef struct sTokenInfo {
1673ae02089SMasatake YAMATO 	tokenType type;
1683ae02089SMasatake YAMATO 	keywordId keyword;
1693ae02089SMasatake YAMATO 	vString *string;		/* the name of the token */
1703ae02089SMasatake YAMATO 	unsigned long lineNumber;	/* line number of tag */
171509a47dbSJiří Techet 	MIOPos filePosition;		/* file position of line containing name */
1723ae02089SMasatake YAMATO } tokenInfo;
1733ae02089SMasatake YAMATO 
1743ae02089SMasatake YAMATO /*
1753ae02089SMasatake YAMATO  *   DATA DEFINITIONS
1763ae02089SMasatake YAMATO  */
1773ae02089SMasatake YAMATO static int Lang_vhdl;
1783ae02089SMasatake YAMATO 
179c02bf7b2SMasatake YAMATO typedef enum {
180c02bf7b2SMasatake YAMATO 	VHDL_ENTITY_DESIGNED,
181c02bf7b2SMasatake YAMATO } vhdlEntityRole;
182c02bf7b2SMasatake YAMATO 
183c02bf7b2SMasatake YAMATO static roleDefinition VhdlEntityRoles [] = {
184c02bf7b2SMasatake YAMATO 	{ true, "desigend",
185c02bf7b2SMasatake YAMATO 	  "designed by an architecture" },
186c02bf7b2SMasatake YAMATO };
187c02bf7b2SMasatake YAMATO 
1883ae02089SMasatake YAMATO /* Used to index into the VhdlKinds table. */
1893ae02089SMasatake YAMATO typedef enum {
1903ae02089SMasatake YAMATO 	VHDLTAG_UNDEFINED = -1,
1913ae02089SMasatake YAMATO 	VHDLTAG_CONSTANT,
1923ae02089SMasatake YAMATO 	VHDLTAG_TYPE,
1933ae02089SMasatake YAMATO 	VHDLTAG_SUBTYPE,
1943ae02089SMasatake YAMATO 	VHDLTAG_RECORD,
1953ae02089SMasatake YAMATO 	VHDLTAG_ENTITY,
1963ae02089SMasatake YAMATO 	VHDLTAG_COMPONENT,
1973ae02089SMasatake YAMATO 	VHDLTAG_PROTOTYPE,
1983ae02089SMasatake YAMATO 	VHDLTAG_FUNCTION,
1993ae02089SMasatake YAMATO 	VHDLTAG_PROCEDURE,
2003ae02089SMasatake YAMATO 	VHDLTAG_PACKAGE,
201b431e6a2SMasatake YAMATO 	VHDLTAG_LOCAL,
202b431e6a2SMasatake YAMATO 	VHDLTAG_ARCHITECTURE,
2030b86d0e9SMasatake YAMATO 	VHDLTAG_PORT,
20438042d43SMasatake YAMATO 	VHDLTAG_GENERIC,
205e9ce313eSMasatake YAMATO 	VHDLTAG_SIGNAL,
206e4754670SMasatake YAMATO 	VHDLTAG_PROCESS,
20708722ce3SMasatake YAMATO 	VHDLTAG_VARIABLE,
208d7cb3fdeSMasatake YAMATO 	VHDLTAG_ALIAS,
2093ae02089SMasatake YAMATO } vhdlKind;
2103ae02089SMasatake YAMATO 
211e112e8abSMasatake YAMATO static kindDefinition VhdlKinds[] = {
212ce990805SThomas Braun 	{true, 'c', "constant", "constant declarations"},
213ce990805SThomas Braun 	{true, 't', "type", "type definitions"},
214ce990805SThomas Braun 	{true, 'T', "subtype", "subtype definitions"},
215ce990805SThomas Braun 	{true, 'r', "record", "record names"},
216c02bf7b2SMasatake YAMATO 	{true, 'e', "entity", "entity declarations",
217c02bf7b2SMasatake YAMATO 	 .referenceOnly = false, ATTACH_ROLES(VhdlEntityRoles)},
218ce990805SThomas Braun 	{false, 'C', "component", "component declarations"},
219ce990805SThomas Braun 	{false, 'd', "prototype", "prototypes"},
220ce990805SThomas Braun 	{true, 'f', "function", "function prototypes and declarations"},
221ce990805SThomas Braun 	{true, 'p', "procedure", "procedure prototypes and declarations"},
222ce990805SThomas Braun 	{true, 'P', "package", "package definitions"},
223b431e6a2SMasatake YAMATO 	{false, 'l', "local", "local definitions"},
224b431e6a2SMasatake YAMATO 	{true, 'a', "architecture", "architectures"},
2250b86d0e9SMasatake YAMATO 	{true, 'q', "port", "port declarations"},
22638042d43SMasatake YAMATO 	{true, 'g', "generic", "generic declarations"},
227e9ce313eSMasatake YAMATO 	{true , 's', "signal", "signal declarations"},
228e4754670SMasatake YAMATO 	{true, 'Q',  "process", "processes"},
22908722ce3SMasatake YAMATO 	{true, 'v',  "variable", "variables"},
230d7cb3fdeSMasatake YAMATO 	{true, 'A',  "alias", "aliases"},
2313ae02089SMasatake YAMATO };
2323ae02089SMasatake YAMATO 
23382c11d8cSRich Siegel static const keywordTable VhdlKeywordTable[] = {
2343ae02089SMasatake YAMATO 	{"abs", KEYWORD_ABS},
2353ae02089SMasatake YAMATO 	{"access", KEYWORD_ACCESS},
2363ae02089SMasatake YAMATO 	{"after", KEYWORD_AFTER},
2373ae02089SMasatake YAMATO 	{"alias", KEYWORD_ALIAS},
2383ae02089SMasatake YAMATO 	{"all", KEYWORD_ALL},
2393ae02089SMasatake YAMATO 	{"and", KEYWORD_AND},
2403ae02089SMasatake YAMATO 	{"architecture", KEYWORD_ARCHITECTURE},
2413ae02089SMasatake YAMATO 	{"array", KEYWORD_ARRAY},
2423ae02089SMasatake YAMATO 	{"assert", KEYWORD_ASSERT},
2433ae02089SMasatake YAMATO 	{"attribute", KEYWORD_ATTRIBUTE},
2443ae02089SMasatake YAMATO 	{"begin", KEYWORD_BEGIN},
2453ae02089SMasatake YAMATO 	{"block", KEYWORD_BLOCK},
2463ae02089SMasatake YAMATO 	{"body", KEYWORD_BODY},
2473ae02089SMasatake YAMATO 	{"buffer", KEYWORD_BUFFER},
2483ae02089SMasatake YAMATO 	{"bus", KEYWORD_BUS},
2493ae02089SMasatake YAMATO 	{"case", KEYWORD_CASE},
2503ae02089SMasatake YAMATO 	{"component", KEYWORD_COMPONENT},
2513ae02089SMasatake YAMATO 	{"configuration", KEYWORD_CONFIGURATION},
2523ae02089SMasatake YAMATO 	{"constant", KEYWORD_CONSTANT},
2533ae02089SMasatake YAMATO 	{"disconnect", KEYWORD_DISCONNECT},
2543ae02089SMasatake YAMATO 	{"downto", KEYWORD_DOWNTO},
2553ae02089SMasatake YAMATO 	{"else", KEYWORD_ELSE},
2563ae02089SMasatake YAMATO 	{"elsif", KEYWORD_ELSIF},
2573ae02089SMasatake YAMATO 	{"end", KEYWORD_END},
2583ae02089SMasatake YAMATO 	{"entity", KEYWORD_ENTITY},
2593ae02089SMasatake YAMATO 	{"exit", KEYWORD_EXIT},
2603ae02089SMasatake YAMATO 	{"file", KEYWORD_FILE},
2613ae02089SMasatake YAMATO 	{"for", KEYWORD_FOR},
2623ae02089SMasatake YAMATO 	{"function", KEYWORD_FUNCTION},
2633ae02089SMasatake YAMATO 	{"generate", KEYWORD_GENERATE},
2643ae02089SMasatake YAMATO 	{"generic", KEYWORD_GENERIC},
2653ae02089SMasatake YAMATO 	{"group", KEYWORD_GROUP},
2663ae02089SMasatake YAMATO 	{"guarded", KEYWORD_GUARDED},
2673ae02089SMasatake YAMATO 	{"if", KEYWORD_IF},
2683ae02089SMasatake YAMATO 	{"impure", KEYWORD_IMPURE},
2693ae02089SMasatake YAMATO 	{"in", KEYWORD_IN},
2703ae02089SMasatake YAMATO 	{"inertial", KEYWORD_INERTIAL},
2713ae02089SMasatake YAMATO 	{"inout", KEYWORD_INOUT},
2723ae02089SMasatake YAMATO 	{"is", KEYWORD_IS},
2733ae02089SMasatake YAMATO 	{"label", KEYWORD_LABEL},
2743ae02089SMasatake YAMATO 	{"library", KEYWORD_LIBRARY},
2753ae02089SMasatake YAMATO 	{"linkage", KEYWORD_LINKAGE},
2763ae02089SMasatake YAMATO 	{"literal", KEYWORD_LITERAL},
2773ae02089SMasatake YAMATO 	{"loop", KEYWORD_LOOP},
2783ae02089SMasatake YAMATO 	{"map", KEYWORD_MAP},
2793ae02089SMasatake YAMATO 	{"mod", KEYWORD_MOD},
2803ae02089SMasatake YAMATO 	{"nand", KEYWORD_NAND},
2813ae02089SMasatake YAMATO 	{"new", KEYWORD_NEW},
2823ae02089SMasatake YAMATO 	{"next", KEYWORD_NEXT},
2833ae02089SMasatake YAMATO 	{"nor", KEYWORD_NOR},
2843ae02089SMasatake YAMATO 	{"not", KEYWORD_NOT},
2853ae02089SMasatake YAMATO 	{"null", KEYWORD_NULL},
2863ae02089SMasatake YAMATO 	{"of", KEYWORD_OF},
2873ae02089SMasatake YAMATO 	{"on", KEYWORD_ON},
2883ae02089SMasatake YAMATO 	{"open", KEYWORD_OPEN},
2893ae02089SMasatake YAMATO 	{"or", KEYWORD_OR},
2903ae02089SMasatake YAMATO 	{"others", KEYWORD_OTHERS},
2913ae02089SMasatake YAMATO 	{"out", KEYWORD_OUT},
2923ae02089SMasatake YAMATO 	{"package", KEYWORD_PACKAGE},
2933ae02089SMasatake YAMATO 	{"port", KEYWORD_PORT},
2943ae02089SMasatake YAMATO 	{"postponed", KEYWORD_POSTPONED},
2953ae02089SMasatake YAMATO 	{"procedure", KEYWORD_PROCEDURE},
2963ae02089SMasatake YAMATO 	{"process", KEYWORD_PROCESS},
2973ae02089SMasatake YAMATO 	{"pure", KEYWORD_PURE},
2983ae02089SMasatake YAMATO 	{"range", KEYWORD_RANGE},
2993ae02089SMasatake YAMATO 	{"record", KEYWORD_RECORD},
3003ae02089SMasatake YAMATO 	{"register", KEYWORD_REGISTER},
3013ae02089SMasatake YAMATO 	{"reject", KEYWORD_REJECT},
3023ae02089SMasatake YAMATO 	{"return", KEYWORD_RETURN},
3033ae02089SMasatake YAMATO 	{"rol", KEYWORD_ROL},
3043ae02089SMasatake YAMATO 	{"ror", KEYWORD_ROR},
3053ae02089SMasatake YAMATO 	{"select", KEYWORD_SELECT},
3063ae02089SMasatake YAMATO 	{"severity", KEYWORD_SEVERITY},
3073ae02089SMasatake YAMATO 	{"signal", KEYWORD_SIGNAL},
3083ae02089SMasatake YAMATO 	{"shared", KEYWORD_SHARED},
3093ae02089SMasatake YAMATO 	{"sla", KEYWORD_SLA},
3103ae02089SMasatake YAMATO 	{"sli", KEYWORD_SLI},
3113ae02089SMasatake YAMATO 	{"sra", KEYWORD_SRA},
3123ae02089SMasatake YAMATO 	{"srl", KEYWORD_SRL},
3133ae02089SMasatake YAMATO 	{"subtype", KEYWORD_SUBTYPE},
3143ae02089SMasatake YAMATO 	{"then", KEYWORD_THEN},
3153ae02089SMasatake YAMATO 	{"to", KEYWORD_TO},
3163ae02089SMasatake YAMATO 	{"transport", KEYWORD_TRANSPORT},
3173ae02089SMasatake YAMATO 	{"type", KEYWORD_TYPE},
3183ae02089SMasatake YAMATO 	{"unaffected", KEYWORD_UNAFFECTED},
3193ae02089SMasatake YAMATO 	{"units", KEYWORD_UNITS},
3203ae02089SMasatake YAMATO 	{"until", KEYWORD_UNTIL},
3213ae02089SMasatake YAMATO 	{"use", KEYWORD_USE},
3223ae02089SMasatake YAMATO 	{"variable", KEYWORD_VARIABLE},
3233ae02089SMasatake YAMATO 	{"wait", KEYWORD_WAIT},
3243ae02089SMasatake YAMATO 	{"when", KEYWORD_WHEN},
3253ae02089SMasatake YAMATO 	{"while", KEYWORD_WHILE},
3263ae02089SMasatake YAMATO 	{"with", KEYWORD_WITH},
3273ae02089SMasatake YAMATO 	{"xnor", KEYWORD_XNOR},
3283ae02089SMasatake YAMATO 	{"xor", KEYWORD_XOR}
3293ae02089SMasatake YAMATO };
3303ae02089SMasatake YAMATO 
331a973df1dSMasatake YAMATO typedef enum {
332a973df1dSMasatake YAMATO 	F_ARCHITECTURE,
333a973df1dSMasatake YAMATO } vhdlField;
334a973df1dSMasatake YAMATO 
335a973df1dSMasatake YAMATO static fieldDefinition VhdlFields [] = {
336a973df1dSMasatake YAMATO 	{ .name = "architecture",
337a973df1dSMasatake YAMATO 	  .description = "architecture designing the entity",
338a973df1dSMasatake YAMATO 	  .enabled = true },
339a973df1dSMasatake YAMATO };
340a973df1dSMasatake YAMATO 
3413ae02089SMasatake YAMATO /*
3423ae02089SMasatake YAMATO  *   FUNCTION DECLARATIONS
3433ae02089SMasatake YAMATO  */
344cf9a5d2eSMasatake YAMATO static void parseKeywords (tokenInfo * const token, tokenInfo * const label, int parent);
3453ae02089SMasatake YAMATO 
3463ae02089SMasatake YAMATO /*
3473ae02089SMasatake YAMATO  *   FUNCTION DEFINITIONS
3483ae02089SMasatake YAMATO  */
isIdentifierMatch(const tokenInfo * const token,const char * name)349ce990805SThomas Braun static bool isIdentifierMatch (const tokenInfo * const token,
350756882bbSMasatake YAMATO 	const char *name)
3513ae02089SMasatake YAMATO {
352ce990805SThomas Braun 	return (bool) (isType (token, TOKEN_IDENTIFIER) &&
3536aa3f13dSMasatake YAMATO 		strncasecmp (vStringValue (token->string), name,
3546aa3f13dSMasatake YAMATO 					 vStringLength (token->string)) == 0);
3553ae02089SMasatake YAMATO }
3563ae02089SMasatake YAMATO 
isSemicolonOrKeywordOrIdent(const tokenInfo * const token,const keywordId keyword,const char * name)357be689381SMasatake YAMATO static bool isSemicolonOrKeywordOrIdent (const tokenInfo * const token,
358756882bbSMasatake YAMATO 	const keywordId keyword, const char *name)
3593ae02089SMasatake YAMATO {
360be689381SMasatake YAMATO 	return (bool) (isType (token, TOKEN_SEMICOLON)
361be689381SMasatake YAMATO 				   || isKeyword (token, keyword)
362be689381SMasatake YAMATO 				   || isIdentifierMatch (token, name));
3633ae02089SMasatake YAMATO }
3643ae02089SMasatake YAMATO 
newToken(void)3653ae02089SMasatake YAMATO static tokenInfo *newToken (void)
3663ae02089SMasatake YAMATO {
3673ae02089SMasatake YAMATO 	tokenInfo *const token = xMalloc (1, tokenInfo);
3683ae02089SMasatake YAMATO 	token->type = TOKEN_NONE;
3693ae02089SMasatake YAMATO 	token->keyword = KEYWORD_NONE;
3703ae02089SMasatake YAMATO 	token->string = vStringNew ();
371a31b37dcSMasatake YAMATO 	token->lineNumber = getInputLineNumber ();
3723ae02089SMasatake YAMATO 	token->filePosition = getInputFilePosition ();
3733ae02089SMasatake YAMATO 	return token;
3743ae02089SMasatake YAMATO }
3753ae02089SMasatake YAMATO 
copyToken(tokenInfo * const src)376cf9a5d2eSMasatake YAMATO static tokenInfo *copyToken (tokenInfo * const src)
377cf9a5d2eSMasatake YAMATO {
378cf9a5d2eSMasatake YAMATO 	tokenInfo *dst = newToken ();
379cf9a5d2eSMasatake YAMATO 	vStringCopy (dst->string, src->string);
380cf9a5d2eSMasatake YAMATO 	return dst;
381cf9a5d2eSMasatake YAMATO }
382cf9a5d2eSMasatake YAMATO 
deleteToken(tokenInfo * const token)3833ae02089SMasatake YAMATO static void deleteToken (tokenInfo * const token)
3843ae02089SMasatake YAMATO {
3853ae02089SMasatake YAMATO 	if (token != NULL)
3863ae02089SMasatake YAMATO 	{
3873ae02089SMasatake YAMATO 		vStringDelete (token->string);
3883ae02089SMasatake YAMATO 		eFree (token);
3893ae02089SMasatake YAMATO 	}
3903ae02089SMasatake YAMATO }
3913ae02089SMasatake YAMATO 
3923ae02089SMasatake YAMATO /*
3933ae02089SMasatake YAMATO  *   Parsing functions
3943ae02089SMasatake YAMATO  */
3953ae02089SMasatake YAMATO 
parseString(vString * const string,const int delimiter)3963ae02089SMasatake YAMATO static void parseString (vString * const string, const int delimiter)
3973ae02089SMasatake YAMATO {
398ce990805SThomas Braun 	bool end = false;
3993ae02089SMasatake YAMATO 	while (!end)
4003ae02089SMasatake YAMATO 	{
401018bce0bSMasatake YAMATO 		int c = getcFromInputFile ();
4023ae02089SMasatake YAMATO 		if (c == EOF)
403ce990805SThomas Braun 			end = true;
4043ae02089SMasatake YAMATO 		else if (c == '\\')
4053ae02089SMasatake YAMATO 		{
406018bce0bSMasatake YAMATO 			c = getcFromInputFile ();	/* This maybe a ' or ". */
4073ae02089SMasatake YAMATO 			vStringPut (string, c);
4083ae02089SMasatake YAMATO 		}
4093ae02089SMasatake YAMATO 		else if (c == delimiter)
410ce990805SThomas Braun 			end = true;
4113ae02089SMasatake YAMATO 		else
4123ae02089SMasatake YAMATO 			vStringPut (string, c);
4133ae02089SMasatake YAMATO 	}
4143ae02089SMasatake YAMATO }
4153ae02089SMasatake YAMATO 
4163ae02089SMasatake YAMATO /*  Read a VHDL identifier beginning with "firstChar" and place it into "name".
4173ae02089SMasatake YAMATO */
parseIdentifier(vString * const string,const int firstChar)4183ae02089SMasatake YAMATO static void parseIdentifier (vString * const string, const int firstChar)
4193ae02089SMasatake YAMATO {
4203ae02089SMasatake YAMATO 	int c = firstChar;
4213ae02089SMasatake YAMATO 	Assert (isIdentChar1 (c));
4223ae02089SMasatake YAMATO 	do
4233ae02089SMasatake YAMATO 	{
4243ae02089SMasatake YAMATO 		vStringPut (string, c);
425018bce0bSMasatake YAMATO 		c = getcFromInputFile ();
4263ae02089SMasatake YAMATO 	} while (isIdentChar (c));
4273ae02089SMasatake YAMATO 	if (!isspace (c))
42861f14fa5SMasatake YAMATO 		ungetcToInputFile (c);	/* unget non-identifier character */
4293ae02089SMasatake YAMATO }
4303ae02089SMasatake YAMATO 
readToken(tokenInfo * const token)4313ae02089SMasatake YAMATO static void readToken (tokenInfo * const token)
4323ae02089SMasatake YAMATO {
4333ae02089SMasatake YAMATO 	int c;
4343ae02089SMasatake YAMATO 
4353ae02089SMasatake YAMATO 	token->type = TOKEN_NONE;
4363ae02089SMasatake YAMATO 	token->keyword = KEYWORD_NONE;
4373ae02089SMasatake YAMATO 	vStringClear (token->string);
4383ae02089SMasatake YAMATO 
4393ae02089SMasatake YAMATO   getNextChar:
4403ae02089SMasatake YAMATO 	do
4413ae02089SMasatake YAMATO 	{
442018bce0bSMasatake YAMATO 		c = getcFromInputFile ();
443a31b37dcSMasatake YAMATO 		token->lineNumber = getInputLineNumber ();
4443ae02089SMasatake YAMATO 		token->filePosition = getInputFilePosition ();
4453ae02089SMasatake YAMATO 	}
4463ae02089SMasatake YAMATO 	while (c == '\t' || c == ' ' || c == '\n');
4473ae02089SMasatake YAMATO 
4483ae02089SMasatake YAMATO 	switch (c)
4493ae02089SMasatake YAMATO 	{
4503ae02089SMasatake YAMATO 	case EOF:
4513ae02089SMasatake YAMATO 		token->type = TOKEN_EOF;
4523ae02089SMasatake YAMATO 		break;
4533ae02089SMasatake YAMATO 	case '(':
4543ae02089SMasatake YAMATO 		token->type = TOKEN_OPEN_PAREN;
4553ae02089SMasatake YAMATO 		break;
4563ae02089SMasatake YAMATO 	case ')':
4573ae02089SMasatake YAMATO 		token->type = TOKEN_CLOSE_PAREN;
4583ae02089SMasatake YAMATO 		break;
4593ae02089SMasatake YAMATO 	case ';':
4603ae02089SMasatake YAMATO 		token->type = TOKEN_SEMICOLON;
4613ae02089SMasatake YAMATO 		break;
4620b86d0e9SMasatake YAMATO 	case ':':
4630b86d0e9SMasatake YAMATO 		token->type = TOKEN_COLON;
4640b86d0e9SMasatake YAMATO 		break;
4653ae02089SMasatake YAMATO 	case '.':
4663ae02089SMasatake YAMATO 		token->type = TOKEN_PERIOD;
4673ae02089SMasatake YAMATO 		break;
4683ae02089SMasatake YAMATO 	case ',':
4693ae02089SMasatake YAMATO 		token->type = TOKEN_COMMA;
4703ae02089SMasatake YAMATO 		break;
4713ae02089SMasatake YAMATO 	case '\'':	/* only single char are inside simple quotes */
4723ae02089SMasatake YAMATO 		break;	/* or it is for attributes so we don't care */
4733ae02089SMasatake YAMATO 	case '"':
4743ae02089SMasatake YAMATO 		token->type = TOKEN_STRING;
4753ae02089SMasatake YAMATO 		parseString (token->string, c);
476a31b37dcSMasatake YAMATO 		token->lineNumber = getInputLineNumber ();
4773ae02089SMasatake YAMATO 		token->filePosition = getInputFilePosition ();
4783ae02089SMasatake YAMATO 		break;
4793ae02089SMasatake YAMATO 	case '-':
480018bce0bSMasatake YAMATO 		c = getcFromInputFile ();
4813ae02089SMasatake YAMATO 		if (c == '-')	/* start of a comment */
4823ae02089SMasatake YAMATO 		{
4834fffc5afSMasatake YAMATO 			skipToCharacterInInputFile ('\n');
4843ae02089SMasatake YAMATO 			goto getNextChar;
4853ae02089SMasatake YAMATO 		}
4863ae02089SMasatake YAMATO 		else
4873ae02089SMasatake YAMATO 		{
4883ae02089SMasatake YAMATO 			if (!isspace (c))
48961f14fa5SMasatake YAMATO 				ungetcToInputFile (c);
4903ae02089SMasatake YAMATO 			token->type = TOKEN_OPERATOR;
4913ae02089SMasatake YAMATO 		}
4923ae02089SMasatake YAMATO 		break;
4933ae02089SMasatake YAMATO 	default:
4943ae02089SMasatake YAMATO 		if (!isIdentChar1 (c))
4953ae02089SMasatake YAMATO 			token->type = TOKEN_NONE;
4963ae02089SMasatake YAMATO 		else
4973ae02089SMasatake YAMATO 		{
4983ae02089SMasatake YAMATO 			parseIdentifier (token->string, c);
499a31b37dcSMasatake YAMATO 			token->lineNumber = getInputLineNumber ();
5003ae02089SMasatake YAMATO 			token->filePosition = getInputFilePosition ();
50131a85388SJiří Techet 			token->keyword = lookupCaseKeyword (vStringValue (token->string), Lang_vhdl);
5023ae02089SMasatake YAMATO 			if (isKeyword (token, KEYWORD_NONE))
5033ae02089SMasatake YAMATO 				token->type = TOKEN_IDENTIFIER;
5043ae02089SMasatake YAMATO 			else
5053ae02089SMasatake YAMATO 				token->type = TOKEN_KEYWORD;
5063ae02089SMasatake YAMATO 		}
5073ae02089SMasatake YAMATO 		break;
5083ae02089SMasatake YAMATO 	}
5093ae02089SMasatake YAMATO }
5103ae02089SMasatake YAMATO 
skipToKeyword(const keywordId keyword)51115c03170SMasatake YAMATO static bool skipToKeyword (const keywordId keyword)
5123ae02089SMasatake YAMATO {
5133ae02089SMasatake YAMATO 	tokenInfo *const token = newToken ();
5143ae02089SMasatake YAMATO 	do
5153ae02089SMasatake YAMATO 	{
5163ae02089SMasatake YAMATO 		readToken (token);
5173ae02089SMasatake YAMATO 	}
5183ae02089SMasatake YAMATO 	while (!isType (token, TOKEN_EOF) && !isKeyword (token, keyword));
51915c03170SMasatake YAMATO 
52015c03170SMasatake YAMATO 	bool r = isKeyword (token, keyword);
5213ae02089SMasatake YAMATO 	deleteToken (token);
52215c03170SMasatake YAMATO 	return r;
5233ae02089SMasatake YAMATO }
5243ae02089SMasatake YAMATO 
skipToMatched(tokenInfo * const token)5253ae02089SMasatake YAMATO static void skipToMatched (tokenInfo * const token)
5263ae02089SMasatake YAMATO {
5273ae02089SMasatake YAMATO 	int nest_level = 0;
5283ae02089SMasatake YAMATO 	tokenType open_token;
5293ae02089SMasatake YAMATO 	tokenType close_token;
5303ae02089SMasatake YAMATO 
5313ae02089SMasatake YAMATO 	switch (token->type)
5323ae02089SMasatake YAMATO 	{
5333ae02089SMasatake YAMATO 	case TOKEN_OPEN_PAREN:
5343ae02089SMasatake YAMATO 		open_token = TOKEN_OPEN_PAREN;
5353ae02089SMasatake YAMATO 		close_token = TOKEN_CLOSE_PAREN;
5363ae02089SMasatake YAMATO 		break;
5373ae02089SMasatake YAMATO 	default:
5383ae02089SMasatake YAMATO 		return;
5393ae02089SMasatake YAMATO 	}
5403ae02089SMasatake YAMATO 
5413ae02089SMasatake YAMATO 	/*
5423ae02089SMasatake YAMATO 	 * This routine will skip to a matching closing token.
5433ae02089SMasatake YAMATO 	 * It will also handle nested tokens like the (, ) below.
5443ae02089SMasatake YAMATO 	 *   (  name varchar(30), text binary(10)  )
5453ae02089SMasatake YAMATO 	 */
5463ae02089SMasatake YAMATO 	if (isType (token, open_token))
5473ae02089SMasatake YAMATO 	{
5483ae02089SMasatake YAMATO 		nest_level++;
5493ae02089SMasatake YAMATO 		while (!(isType (token, close_token) && (nest_level == 0)) && !isType (token, TOKEN_EOF))
5503ae02089SMasatake YAMATO 		{
5513ae02089SMasatake YAMATO 			readToken (token);
5523ae02089SMasatake YAMATO 			if (isType (token, open_token))
5533ae02089SMasatake YAMATO 			{
5543ae02089SMasatake YAMATO 				nest_level++;
5553ae02089SMasatake YAMATO 			}
5563ae02089SMasatake YAMATO 			if (isType (token, close_token))
5573ae02089SMasatake YAMATO 			{
5583ae02089SMasatake YAMATO 				if (nest_level > 0)
5593ae02089SMasatake YAMATO 				{
5603ae02089SMasatake YAMATO 					nest_level--;
5613ae02089SMasatake YAMATO 				}
5623ae02089SMasatake YAMATO 			}
5633ae02089SMasatake YAMATO 		}
5643ae02089SMasatake YAMATO 		readToken (token);
5653ae02089SMasatake YAMATO 	}
5663ae02089SMasatake YAMATO }
5673ae02089SMasatake YAMATO 
makeVhdlTagWithScope(tokenInfo * const token,const vhdlKind kind,int parent)5681b455c98SMasatake YAMATO static int makeVhdlTagWithScope (tokenInfo * const token, const vhdlKind kind, int parent)
5693ae02089SMasatake YAMATO {
5703ae02089SMasatake YAMATO 	const char *const name = vStringValue (token->string);
5713ae02089SMasatake YAMATO 	tagEntryInfo e;
57216a2541cSMasatake YAMATO 	initTagEntry (&e, name, kind);
5733ae02089SMasatake YAMATO 	e.lineNumber = token->lineNumber;
5743ae02089SMasatake YAMATO 	e.filePosition = token->filePosition;
5751b455c98SMasatake YAMATO 	e.extensionFields.scopeIndex = parent;
5764d10e2acSMasatake YAMATO 	return makeTagEntry (&e);
5773ae02089SMasatake YAMATO }
5783ae02089SMasatake YAMATO 
makeVhdlTag(tokenInfo * const token,const vhdlKind kind)579b431e6a2SMasatake YAMATO static int makeVhdlTag (tokenInfo * const token, const vhdlKind kind)
5803ae02089SMasatake YAMATO {
5811b455c98SMasatake YAMATO 	return makeVhdlTagWithScope (token, kind, CORK_NIL);
5820b86d0e9SMasatake YAMATO }
5830b86d0e9SMasatake YAMATO 
initialize(const langType language)5843ae02089SMasatake YAMATO static void initialize (const langType language)
5853ae02089SMasatake YAMATO {
5863ae02089SMasatake YAMATO 	Lang_vhdl = language;
5873ae02089SMasatake YAMATO }
5883ae02089SMasatake YAMATO 
parseTillEnd(tokenInfo * const token,int parent,const int end_keyword)589e8fbd598SMasatake YAMATO static void parseTillEnd (tokenInfo * const token, int parent, const int end_keyword)
590e8fbd598SMasatake YAMATO {
591e8fbd598SMasatake YAMATO 	bool ended = false;
592e8fbd598SMasatake YAMATO 	tagEntryInfo *e = getEntryInCorkQueue (parent);
593acc76baaSMasatake YAMATO 	/* If e is NULL, the input may be broken as VHDL code
594acc76baaSMasatake YAMATO 	 * or unsupported syntax in this parser. */
595e8fbd598SMasatake YAMATO 
596e8fbd598SMasatake YAMATO 	do
597e8fbd598SMasatake YAMATO 	{
598e8fbd598SMasatake YAMATO 		readToken (token);
599e8fbd598SMasatake YAMATO 		if (isKeyword (token, KEYWORD_END))
600e8fbd598SMasatake YAMATO 		{
601e8fbd598SMasatake YAMATO 			readToken (token);
602acc76baaSMasatake YAMATO 			if (e)
603e8fbd598SMasatake YAMATO 				ended = isSemicolonOrKeywordOrIdent (token,
604acc76baaSMasatake YAMATO 													 end_keyword, e->name);
605e8fbd598SMasatake YAMATO 			if (!isType (token, TOKEN_SEMICOLON))
606e8fbd598SMasatake YAMATO 				skipToCharacterInInputFile (';');
60715c03170SMasatake YAMATO 			if (ended)
60815c03170SMasatake YAMATO 				e->extensionFields.endLine = getInputLineNumber ();
609e8fbd598SMasatake YAMATO 		}
610e8fbd598SMasatake YAMATO 		else
611e8fbd598SMasatake YAMATO 		{
612e8fbd598SMasatake YAMATO 			if (isType (token, TOKEN_EOF))
613e8fbd598SMasatake YAMATO 			{
614e8fbd598SMasatake YAMATO 				ended = true;
615e8fbd598SMasatake YAMATO 			}
616e8fbd598SMasatake YAMATO 			else
617e8fbd598SMasatake YAMATO 			{
618e4754670SMasatake YAMATO 				parseKeywords (token, NULL, parent);
619e8fbd598SMasatake YAMATO 			}
620e8fbd598SMasatake YAMATO 		}
621e8fbd598SMasatake YAMATO 	} while (!ended);
622e8fbd598SMasatake YAMATO }
623e8fbd598SMasatake YAMATO 
parseTillBegin(tokenInfo * const token,int parent)62455fd2bd3SMasatake YAMATO static void parseTillBegin (tokenInfo * const token, int parent)
62555fd2bd3SMasatake YAMATO {
62655fd2bd3SMasatake YAMATO 	bool begun = false;
62755fd2bd3SMasatake YAMATO 	do
62855fd2bd3SMasatake YAMATO 	{
62955fd2bd3SMasatake YAMATO 		readToken (token);
63055fd2bd3SMasatake YAMATO 		if (isKeyword (token, KEYWORD_BEGIN)
63155fd2bd3SMasatake YAMATO 			|| isType (token, TOKEN_EOF))
63255fd2bd3SMasatake YAMATO 			begun = true;
63355fd2bd3SMasatake YAMATO 		else
634e4754670SMasatake YAMATO 			parseKeywords (token, NULL, parent);
63555fd2bd3SMasatake YAMATO 	} while (!begun);
63655fd2bd3SMasatake YAMATO }
63755fd2bd3SMasatake YAMATO 
parsePackage(tokenInfo * const token)6383ae02089SMasatake YAMATO static void parsePackage (tokenInfo * const token)
6393ae02089SMasatake YAMATO {
6403ae02089SMasatake YAMATO 	tokenInfo *const name = newToken ();
641433ee3bbSMasatake YAMATO 	tokenInfo *token_for_tagging = NULL;
6423ae02089SMasatake YAMATO 	Assert (isKeyword (token, KEYWORD_PACKAGE));
6433ae02089SMasatake YAMATO 	readToken (token);
6443ae02089SMasatake YAMATO 	if (isKeyword (token, KEYWORD_BODY))
6453ae02089SMasatake YAMATO 	{
6463ae02089SMasatake YAMATO 		readToken (name);
647433ee3bbSMasatake YAMATO 		token_for_tagging = name;
6483ae02089SMasatake YAMATO 	}
6493ae02089SMasatake YAMATO 	else if (isType (token, TOKEN_IDENTIFIER))
650433ee3bbSMasatake YAMATO 		token_for_tagging = token;
651433ee3bbSMasatake YAMATO 
652433ee3bbSMasatake YAMATO 	if (token_for_tagging)
6533ae02089SMasatake YAMATO 	{
654433ee3bbSMasatake YAMATO 		int index = makeVhdlTag (token_for_tagging, VHDLTAG_PACKAGE);
655433ee3bbSMasatake YAMATO 		parseTillEnd (token, index, KEYWORD_PACKAGE);
6563ae02089SMasatake YAMATO 	}
657433ee3bbSMasatake YAMATO 
6583ae02089SMasatake YAMATO 	deleteToken (name);
6593ae02089SMasatake YAMATO }
6603ae02089SMasatake YAMATO 
6610b86d0e9SMasatake YAMATO 
parseDeclElement(tokenInfo * const token,vhdlKind kind,int parent,bool ended_with_semicolon)662e9ce313eSMasatake YAMATO static void parseDeclElement (tokenInfo * const token,
663e9ce313eSMasatake YAMATO 							  vhdlKind kind, int parent,
664e9ce313eSMasatake YAMATO 							  bool ended_with_semicolon)
6650b86d0e9SMasatake YAMATO {
6660b86d0e9SMasatake YAMATO 	TRACE_ENTER ();
6670b86d0e9SMasatake YAMATO 	while (! (isType (token, TOKEN_EOF)
668e9ce313eSMasatake YAMATO 			  || isType (token, TOKEN_CLOSE_PAREN)
669e9ce313eSMasatake YAMATO 			  || (ended_with_semicolon && isType (token, TOKEN_SEMICOLON))))
6700b86d0e9SMasatake YAMATO 	{
6710b86d0e9SMasatake YAMATO 		if (isType (token, TOKEN_IDENTIFIER))
6720b86d0e9SMasatake YAMATO 		{
67338042d43SMasatake YAMATO 			makeVhdlTagWithScope (token, kind, parent);
6740b86d0e9SMasatake YAMATO 			readToken (token);
6750b86d0e9SMasatake YAMATO 		}
6760b86d0e9SMasatake YAMATO 		else if (isType (token, TOKEN_COMMA))
6770b86d0e9SMasatake YAMATO 			readToken (token);
6780b86d0e9SMasatake YAMATO 		else if (isType (token, TOKEN_COLON))
6790b86d0e9SMasatake YAMATO 		{
6800b86d0e9SMasatake YAMATO 			do
6810b86d0e9SMasatake YAMATO 			{
6820b86d0e9SMasatake YAMATO 				readToken (token);
6830b86d0e9SMasatake YAMATO 				skipToMatched (token);
6840b86d0e9SMasatake YAMATO 				if (isType (token, TOKEN_CLOSE_PAREN)
6850b86d0e9SMasatake YAMATO 					|| isType (token, TOKEN_SEMICOLON))
6860b86d0e9SMasatake YAMATO 					break;
6870b86d0e9SMasatake YAMATO 			}
6880b86d0e9SMasatake YAMATO 			while (!isType (token, TOKEN_EOF));
6890b86d0e9SMasatake YAMATO 		}
6900b86d0e9SMasatake YAMATO 		else
6910b86d0e9SMasatake YAMATO 		{
6920b86d0e9SMasatake YAMATO 			/* Unexpected */
6930b86d0e9SMasatake YAMATO 			readToken (token);
6940b86d0e9SMasatake YAMATO 		}
6950b86d0e9SMasatake YAMATO 	}
6960b86d0e9SMasatake YAMATO 	TRACE_LEAVE ();
6970b86d0e9SMasatake YAMATO }
6980b86d0e9SMasatake YAMATO 
parseModuleDecl(tokenInfo * const token,int parent)699efa9acf8SMasatake YAMATO static void parseModuleDecl (tokenInfo * const token, int parent)
7000b86d0e9SMasatake YAMATO {
7010b86d0e9SMasatake YAMATO 	TRACE_ENTER ();
7020b86d0e9SMasatake YAMATO 	while (! (isKeyword (token, KEYWORD_END)
7030b86d0e9SMasatake YAMATO 			  || isType (token, TOKEN_EOF)))
7040b86d0e9SMasatake YAMATO 	{
70538042d43SMasatake YAMATO 		vhdlKind kind = VHDLTAG_UNDEFINED;
7060b86d0e9SMasatake YAMATO 		if (isKeyword (token, KEYWORD_PORT))
70738042d43SMasatake YAMATO 			kind = VHDLTAG_PORT;
70838042d43SMasatake YAMATO 		else if (isKeyword (token, KEYWORD_GENERIC))
70938042d43SMasatake YAMATO 			kind = VHDLTAG_GENERIC;
71038042d43SMasatake YAMATO 
71138042d43SMasatake YAMATO 		if (kind != VHDLTAG_UNDEFINED)
7120b86d0e9SMasatake YAMATO 		{
7130b86d0e9SMasatake YAMATO 			readToken (token);
7140b86d0e9SMasatake YAMATO 			if (isType (token, TOKEN_OPEN_PAREN))
7150b86d0e9SMasatake YAMATO 			{
7160b86d0e9SMasatake YAMATO 				readToken (token);
717e9ce313eSMasatake YAMATO 				parseDeclElement (token, kind, parent, false);
7180b86d0e9SMasatake YAMATO 			}
7190b86d0e9SMasatake YAMATO 		}
7200b86d0e9SMasatake YAMATO 		else
7210b86d0e9SMasatake YAMATO 			readToken (token);
7220b86d0e9SMasatake YAMATO 	}
7230b86d0e9SMasatake YAMATO 	TRACE_LEAVE ();
7240b86d0e9SMasatake YAMATO }
7250b86d0e9SMasatake YAMATO 
parseModule(tokenInfo * const token,int parent)726327cbe54SMasatake YAMATO static void parseModule (tokenInfo * const token, int parent)
7273ae02089SMasatake YAMATO {
7283ae02089SMasatake YAMATO 	tokenInfo *const name = newToken ();
7293ae02089SMasatake YAMATO 	const vhdlKind kind = isKeyword (token, KEYWORD_ENTITY) ?
7303ae02089SMasatake YAMATO 		VHDLTAG_ENTITY : VHDLTAG_COMPONENT;
7313ae02089SMasatake YAMATO 	Assert (isKeyword (token, KEYWORD_ENTITY) ||
7323ae02089SMasatake YAMATO 		isKeyword (token, KEYWORD_COMPONENT));
7333ae02089SMasatake YAMATO 	readToken (name);
7343ae02089SMasatake YAMATO 	readToken (token);
735b109e3f1SMasatake YAMATO 	if (kind == VHDLTAG_COMPONENT || isKeyword (token, KEYWORD_IS))
7363ae02089SMasatake YAMATO 	{
737327cbe54SMasatake YAMATO 		int index = makeVhdlTagWithScope (name, kind, parent);
738b109e3f1SMasatake YAMATO 		if (isKeyword (token, KEYWORD_IS))
7390b86d0e9SMasatake YAMATO 			readToken (token);
740efa9acf8SMasatake YAMATO 		parseModuleDecl (token, index);
74115c03170SMasatake YAMATO 
74215c03170SMasatake YAMATO 		bool ended = isKeyword (token, KEYWORD_END);
74315c03170SMasatake YAMATO 		if (!ended)
74415c03170SMasatake YAMATO 			ended = skipToKeyword (KEYWORD_END);
7454fffc5afSMasatake YAMATO 		skipToCharacterInInputFile (';');
74615c03170SMasatake YAMATO 
74715c03170SMasatake YAMATO 		if (ended)
74815c03170SMasatake YAMATO 		{
74915c03170SMasatake YAMATO 			tagEntryInfo *e = getEntryInCorkQueue (index);
75015c03170SMasatake YAMATO 			if (e)
75115c03170SMasatake YAMATO 				e->extensionFields.endLine = getInputLineNumber ();
75215c03170SMasatake YAMATO 		}
75315c03170SMasatake YAMATO 
754c02bf7b2SMasatake YAMATO 		if (kind == VHDLTAG_ENTITY)
755c02bf7b2SMasatake YAMATO 			registerEntry (index);
7563ae02089SMasatake YAMATO 	}
7573ae02089SMasatake YAMATO 	deleteToken (name);
7583ae02089SMasatake YAMATO }
7593ae02089SMasatake YAMATO 
parseRecord(tokenInfo * const token,int parent)760856a0659SMasatake YAMATO static void parseRecord (tokenInfo * const token, int parent)
7613ae02089SMasatake YAMATO {
7623ae02089SMasatake YAMATO 	tokenInfo *const name = newToken ();
7633ae02089SMasatake YAMATO 	Assert (isKeyword (token, KEYWORD_RECORD));
7643ae02089SMasatake YAMATO 	readToken (name);
7653ae02089SMasatake YAMATO 	do
7663ae02089SMasatake YAMATO 	{
7673ae02089SMasatake YAMATO 		readToken (token);	/* should be a colon */
7684fffc5afSMasatake YAMATO 		skipToCharacterInInputFile (';');
769856a0659SMasatake YAMATO 		makeVhdlTagWithScope (name, VHDLTAG_RECORD, parent);
7703ae02089SMasatake YAMATO 		readToken (name);
7713ae02089SMasatake YAMATO 	}
7723ae02089SMasatake YAMATO 	while (!isKeyword (name, KEYWORD_END) && !isType (name, TOKEN_EOF));
7734fffc5afSMasatake YAMATO 	skipToCharacterInInputFile (';');
77415c03170SMasatake YAMATO 
77515c03170SMasatake YAMATO 	if (isKeyword (name, KEYWORD_END))
77615c03170SMasatake YAMATO 	{
77715c03170SMasatake YAMATO 		tagEntryInfo *e = getEntryInCorkQueue (parent);
77815c03170SMasatake YAMATO 		if (e)
77915c03170SMasatake YAMATO 			e->extensionFields.endLine = getInputLineNumber ();
78015c03170SMasatake YAMATO 	}
78115c03170SMasatake YAMATO 
7823ae02089SMasatake YAMATO 	deleteToken (name);
7833ae02089SMasatake YAMATO }
7843ae02089SMasatake YAMATO 
parseTypes(tokenInfo * const token,int parent)7858da1f11bSMasatake YAMATO static void parseTypes (tokenInfo * const token, int parent)
7863ae02089SMasatake YAMATO {
7873ae02089SMasatake YAMATO 	tokenInfo *const name = newToken ();
7883ae02089SMasatake YAMATO 	const vhdlKind kind = isKeyword (token, KEYWORD_TYPE) ?
7893ae02089SMasatake YAMATO 		VHDLTAG_TYPE : VHDLTAG_SUBTYPE;
7903ae02089SMasatake YAMATO 	Assert (isKeyword (token, KEYWORD_TYPE) ||
7913ae02089SMasatake YAMATO 		isKeyword (token, KEYWORD_SUBTYPE));
7923ae02089SMasatake YAMATO 	readToken (name);
7933ae02089SMasatake YAMATO 	readToken (token);
7943ae02089SMasatake YAMATO 	if (isKeyword (token, KEYWORD_IS))
7953ae02089SMasatake YAMATO 	{
7963ae02089SMasatake YAMATO 		readToken (token);	/* type */
7973ae02089SMasatake YAMATO 		if (isKeyword (token, KEYWORD_RECORD))
7983ae02089SMasatake YAMATO 		{
799856a0659SMasatake YAMATO 			int index = makeVhdlTagWithScope (name, kind, parent);
8003ae02089SMasatake YAMATO 			/*TODO: make tags of the record's names */
801856a0659SMasatake YAMATO 			parseRecord (token, index);
8023ae02089SMasatake YAMATO 		}
8033ae02089SMasatake YAMATO 		else
8043ae02089SMasatake YAMATO 		{
8058da1f11bSMasatake YAMATO 			makeVhdlTagWithScope (name, kind, parent);
8063ae02089SMasatake YAMATO 		}
8073ae02089SMasatake YAMATO 	}
8083ae02089SMasatake YAMATO 	deleteToken (name);
8093ae02089SMasatake YAMATO }
8103ae02089SMasatake YAMATO 
parseConstant(int parent)811a6b1a27fSMasatake YAMATO static void parseConstant (int parent)
8123ae02089SMasatake YAMATO {
813a6b1a27fSMasatake YAMATO 	vhdlKind parent_kind = VHDLTAG_UNDEFINED;
814a6b1a27fSMasatake YAMATO 	tagEntryInfo *e = getEntryInCorkQueue (parent);
815a6b1a27fSMasatake YAMATO 	if (e)
816a6b1a27fSMasatake YAMATO 		parent_kind = e->kindIndex;
817a6b1a27fSMasatake YAMATO 
818a6b1a27fSMasatake YAMATO 	vhdlKind kind;
819a6b1a27fSMasatake YAMATO 	switch (parent_kind)
820a6b1a27fSMasatake YAMATO 	{
821a6b1a27fSMasatake YAMATO 	case VHDLTAG_FUNCTION:
822a6b1a27fSMasatake YAMATO 	case VHDLTAG_PROCEDURE:
823a6b1a27fSMasatake YAMATO 		kind = VHDLTAG_LOCAL;
824a6b1a27fSMasatake YAMATO 		break;
825a6b1a27fSMasatake YAMATO 	default:
826a6b1a27fSMasatake YAMATO 		kind = VHDLTAG_CONSTANT;
827a6b1a27fSMasatake YAMATO 		break;
828a6b1a27fSMasatake YAMATO 	}
829a6b1a27fSMasatake YAMATO 
8303ae02089SMasatake YAMATO 	tokenInfo *const name = newToken ();
8313ae02089SMasatake YAMATO 	readToken (name);
832a6b1a27fSMasatake YAMATO 	makeVhdlTagWithScope (name, kind, parent);
8334fffc5afSMasatake YAMATO 	skipToCharacterInInputFile (';');
8343ae02089SMasatake YAMATO 	deleteToken (name);
8353ae02089SMasatake YAMATO }
8363ae02089SMasatake YAMATO 
parseSubProgram(tokenInfo * const token,int parent)837433ee3bbSMasatake YAMATO static void parseSubProgram (tokenInfo * const token, int parent)
8383ae02089SMasatake YAMATO {
8393ae02089SMasatake YAMATO 	tokenInfo *const name = newToken ();
8403ae02089SMasatake YAMATO 	const vhdlKind kind = isKeyword (token, KEYWORD_FUNCTION) ?
8413ae02089SMasatake YAMATO 		VHDLTAG_FUNCTION : VHDLTAG_PROCEDURE;
84251723783SMasatake YAMATO 	const int end_keyword = token->keyword;
8433ae02089SMasatake YAMATO 	Assert (isKeyword (token, KEYWORD_FUNCTION) ||
8443ae02089SMasatake YAMATO 		isKeyword (token, KEYWORD_PROCEDURE));
8453ae02089SMasatake YAMATO 	readToken (name);	/* the name of the function or procedure */
8463ae02089SMasatake YAMATO 	readToken (token);
8473ae02089SMasatake YAMATO 	if (isType (token, TOKEN_OPEN_PAREN))
8483ae02089SMasatake YAMATO 	{
8493ae02089SMasatake YAMATO 		skipToMatched (token);
8503ae02089SMasatake YAMATO 	}
8513ae02089SMasatake YAMATO 
8523ae02089SMasatake YAMATO 	if (kind == VHDLTAG_FUNCTION)
8533ae02089SMasatake YAMATO 	{
8543ae02089SMasatake YAMATO 		if (isKeyword (token, KEYWORD_RETURN))
8553ae02089SMasatake YAMATO 		{
8563ae02089SMasatake YAMATO 			/* Read datatype */
8573ae02089SMasatake YAMATO 			readToken (token);
8583ae02089SMasatake YAMATO 			while (! isKeyword (token, KEYWORD_IS) &&
8593ae02089SMasatake YAMATO 					! isType (token, TOKEN_SEMICOLON) &&
8603ae02089SMasatake YAMATO 					! isType (token, TOKEN_EOF))
8613ae02089SMasatake YAMATO 			{
8623ae02089SMasatake YAMATO 				readToken (token);
8633ae02089SMasatake YAMATO 			}
8643ae02089SMasatake YAMATO 		}
8653ae02089SMasatake YAMATO 	}
8663ae02089SMasatake YAMATO 
8673ae02089SMasatake YAMATO 	if (isType (token, TOKEN_SEMICOLON))
8683ae02089SMasatake YAMATO 	{
869433ee3bbSMasatake YAMATO 		makeVhdlTagWithScope (name, VHDLTAG_PROTOTYPE, parent);
8703ae02089SMasatake YAMATO 	}
8713ae02089SMasatake YAMATO 	else if (isKeyword (token, KEYWORD_IS))
8723ae02089SMasatake YAMATO 	{
873433ee3bbSMasatake YAMATO 		int index = makeVhdlTagWithScope (name, kind, parent);
874e8fbd598SMasatake YAMATO 		parseTillEnd (token, index, end_keyword);
8753ae02089SMasatake YAMATO 	}
8763ae02089SMasatake YAMATO 	deleteToken (name);
8773ae02089SMasatake YAMATO }
8783ae02089SMasatake YAMATO 
879b431e6a2SMasatake YAMATO /*  architecture behavioral of ent is*/
parseArchitecture(tokenInfo * const token)880b431e6a2SMasatake YAMATO static void parseArchitecture (tokenInfo * const token)
881b431e6a2SMasatake YAMATO {
882b431e6a2SMasatake YAMATO 	tokenInfo *const name = newToken ();
883b431e6a2SMasatake YAMATO 
884b431e6a2SMasatake YAMATO 	readToken (name);
885b431e6a2SMasatake YAMATO 	if (!isType (name, TOKEN_IDENTIFIER))
886b431e6a2SMasatake YAMATO 	{
887b431e6a2SMasatake YAMATO 		skipToKeyword (KEYWORD_END);
888b431e6a2SMasatake YAMATO 		skipToCharacterInInputFile (';');
889b431e6a2SMasatake YAMATO 		deleteToken (name);
890b431e6a2SMasatake YAMATO 		return;
891b431e6a2SMasatake YAMATO 	}
892b431e6a2SMasatake YAMATO 
893b431e6a2SMasatake YAMATO 	int index = makeVhdlTag (name, VHDLTAG_ARCHITECTURE);
894b431e6a2SMasatake YAMATO 	readToken (token);
895b431e6a2SMasatake YAMATO 	if (isKeyword (token, KEYWORD_OF))
896b431e6a2SMasatake YAMATO 	{
897b431e6a2SMasatake YAMATO 		readToken (token);
898b431e6a2SMasatake YAMATO 		if (isType (token, TOKEN_IDENTIFIER))
899b431e6a2SMasatake YAMATO 		{
900c02bf7b2SMasatake YAMATO 			/* Filling scope field of this architecture.
901c02bf7b2SMasatake YAMATO 			   If the definition for the entity can be found in the symbol table,
902c02bf7b2SMasatake YAMATO 			   use its cork as the scope. If not, use the reference tag for the
903c02bf7b2SMasatake YAMATO 			   entity as fallback. */
904c02bf7b2SMasatake YAMATO 			int role_index = makeSimpleRefTag (token->string,
905c02bf7b2SMasatake YAMATO 											   VHDLTAG_ENTITY, VHDL_ENTITY_DESIGNED);
906c02bf7b2SMasatake YAMATO 			int entity_index = anyKindEntryInScope (CORK_NIL,
907c02bf7b2SMasatake YAMATO 													vStringValue (token->string),
908*aaaac7eeSMasatake YAMATO 													VHDLTAG_ENTITY,
909*aaaac7eeSMasatake YAMATO 													false);
910c02bf7b2SMasatake YAMATO 			tagEntryInfo *e = getEntryInCorkQueue (index);
911c02bf7b2SMasatake YAMATO 			if (e)
912a973df1dSMasatake YAMATO 			{
913c02bf7b2SMasatake YAMATO 				e->extensionFields.scopeIndex = (
914c02bf7b2SMasatake YAMATO 					entity_index == CORK_NIL
915c02bf7b2SMasatake YAMATO 					? role_index
916c02bf7b2SMasatake YAMATO 					: entity_index);
917c02bf7b2SMasatake YAMATO 
918a973df1dSMasatake YAMATO 				/* TODO: append thes architecture name to
919a973df1dSMasatake YAMATO 				 * architecture: field of *e*. */
920a973df1dSMasatake YAMATO 			}
921a973df1dSMasatake YAMATO 
922a973df1dSMasatake YAMATO 			attachParserFieldToCorkEntry (role_index,
923a973df1dSMasatake YAMATO 										  VhdlFields[F_ARCHITECTURE].ftype,
924a973df1dSMasatake YAMATO 										  vStringValue (name->string));
925a973df1dSMasatake YAMATO 
92655fd2bd3SMasatake YAMATO 			readToken (token);
92755fd2bd3SMasatake YAMATO 			if (isKeyword (token, KEYWORD_IS))
92855fd2bd3SMasatake YAMATO 			{
92955fd2bd3SMasatake YAMATO 				parseTillBegin (token, index);
93055fd2bd3SMasatake YAMATO 				parseTillEnd (token, index, KEYWORD_ARCHITECTURE);
93155fd2bd3SMasatake YAMATO 			}
932b431e6a2SMasatake YAMATO 		}
933b431e6a2SMasatake YAMATO 	}
934b431e6a2SMasatake YAMATO 	deleteToken (name);
935b431e6a2SMasatake YAMATO }
936b431e6a2SMasatake YAMATO 
parseSignal(tokenInfo * const token,int parent)937e9ce313eSMasatake YAMATO static void parseSignal (tokenInfo * const token, int parent)
938e9ce313eSMasatake YAMATO {
939e9ce313eSMasatake YAMATO 	readToken (token);
940e9ce313eSMasatake YAMATO 	parseDeclElement (token, VHDLTAG_SIGNAL, parent, true);
941e9ce313eSMasatake YAMATO }
942e9ce313eSMasatake YAMATO 
parseLabel(tokenInfo * const name,int parent)943e4754670SMasatake YAMATO static void parseLabel (tokenInfo * const name, int parent)
944e4754670SMasatake YAMATO {
945e4754670SMasatake YAMATO 	tokenInfo *const token = newToken ();
946e4754670SMasatake YAMATO 
947e4754670SMasatake YAMATO 	readToken (token);
948e4754670SMasatake YAMATO 	if (isType (token, TOKEN_COLON))
949e4754670SMasatake YAMATO 	{
950e4754670SMasatake YAMATO 		readToken (token);
951e4754670SMasatake YAMATO 		if (isType (token, TOKEN_KEYWORD))
952cf9a5d2eSMasatake YAMATO 			parseKeywords (token, name, parent);
953e4754670SMasatake YAMATO 	}
954e4754670SMasatake YAMATO 	deleteToken (token);
955e4754670SMasatake YAMATO }
956e4754670SMasatake YAMATO 
parseProcess(tokenInfo * const token,tokenInfo * const label,int parent)957cf9a5d2eSMasatake YAMATO static void parseProcess (tokenInfo * const token, tokenInfo * const label, int parent)
958e4754670SMasatake YAMATO {
959cf9a5d2eSMasatake YAMATO 	tokenInfo *process = label? label: copyToken (token);
960e4754670SMasatake YAMATO 
961e4754670SMasatake YAMATO 	if (label == NULL)
962cf9a5d2eSMasatake YAMATO 	{
963cf9a5d2eSMasatake YAMATO 		process->type = TOKEN_IDENTIFIER;
964cf9a5d2eSMasatake YAMATO 		vStringClear (process->string);
965cf9a5d2eSMasatake YAMATO 		anonGenerate (process->string, "anonProcess", VHDLTAG_PROCESS);
966cf9a5d2eSMasatake YAMATO 	}
967e4754670SMasatake YAMATO 
968cf9a5d2eSMasatake YAMATO 	int index = makeVhdlTagWithScope (process, VHDLTAG_PROCESS, parent);
969e4754670SMasatake YAMATO 
970e4754670SMasatake YAMATO 	if (label == NULL)
971e4754670SMasatake YAMATO 	{
972e4754670SMasatake YAMATO 		tagEntryInfo *e = getEntryInCorkQueue (index);
973e4754670SMasatake YAMATO 		if (e)
974e4754670SMasatake YAMATO 			markTagExtraBit (e, XTAG_ANONYMOUS);
975cf9a5d2eSMasatake YAMATO 		deleteToken (process);
976e4754670SMasatake YAMATO 	}
977e4754670SMasatake YAMATO 
978e4754670SMasatake YAMATO 	skipToMatched (token);
979e4754670SMasatake YAMATO 	parseTillBegin (token, index);
980e4754670SMasatake YAMATO 	parseTillEnd (token, index, KEYWORD_PROCESS);
981e4754670SMasatake YAMATO }
982e4754670SMasatake YAMATO 
parseVariable(tokenInfo * const token,int parent)98308722ce3SMasatake YAMATO static void parseVariable (tokenInfo * const token, int parent)
98408722ce3SMasatake YAMATO {
98508722ce3SMasatake YAMATO 	readToken (token);
98608722ce3SMasatake YAMATO 	parseDeclElement (token, VHDLTAG_VARIABLE, parent, true);
98708722ce3SMasatake YAMATO }
98808722ce3SMasatake YAMATO 
parseAlias(tokenInfo * const token,int parent)989d7cb3fdeSMasatake YAMATO static void parseAlias (tokenInfo * const token, int parent)
990d7cb3fdeSMasatake YAMATO {
991d7cb3fdeSMasatake YAMATO 	readToken (token);
992d7cb3fdeSMasatake YAMATO 	parseDeclElement (token, VHDLTAG_ALIAS, parent, true);
993d7cb3fdeSMasatake YAMATO }
994d7cb3fdeSMasatake YAMATO 
9953ae02089SMasatake YAMATO /* TODO */
9963ae02089SMasatake YAMATO /* records */
parseKeywords(tokenInfo * const token,tokenInfo * const label,int index)997cf9a5d2eSMasatake YAMATO static void parseKeywords (tokenInfo * const token, tokenInfo * const label, int index)
9983ae02089SMasatake YAMATO {
9993ae02089SMasatake YAMATO 	switch (token->keyword)
10003ae02089SMasatake YAMATO 	{
10013ae02089SMasatake YAMATO 	case KEYWORD_END:
10024fffc5afSMasatake YAMATO 		skipToCharacterInInputFile (';');
10033ae02089SMasatake YAMATO 		break;
10043ae02089SMasatake YAMATO 	case KEYWORD_CONSTANT:
1005a6b1a27fSMasatake YAMATO 		parseConstant (index);
10063ae02089SMasatake YAMATO 		break;
10073ae02089SMasatake YAMATO 	case KEYWORD_TYPE:
10088da1f11bSMasatake YAMATO 		parseTypes (token, index);
10093ae02089SMasatake YAMATO 		break;
10103ae02089SMasatake YAMATO 	case KEYWORD_SUBTYPE:
10118da1f11bSMasatake YAMATO 		parseTypes (token, index);
10123ae02089SMasatake YAMATO 		break;
10133ae02089SMasatake YAMATO 	case KEYWORD_ENTITY:
1014327cbe54SMasatake YAMATO 		parseModule (token, index);
10153ae02089SMasatake YAMATO 		break;
10163ae02089SMasatake YAMATO 	case KEYWORD_COMPONENT:
1017327cbe54SMasatake YAMATO 		parseModule (token, index);
10183ae02089SMasatake YAMATO 		break;
10193ae02089SMasatake YAMATO 	case KEYWORD_FUNCTION:
1020433ee3bbSMasatake YAMATO 		parseSubProgram (token, index);
10213ae02089SMasatake YAMATO 		break;
10223ae02089SMasatake YAMATO 	case KEYWORD_PROCEDURE:
1023433ee3bbSMasatake YAMATO 		parseSubProgram (token, index);
10243ae02089SMasatake YAMATO 		break;
10253ae02089SMasatake YAMATO 	case KEYWORD_PACKAGE:
10263ae02089SMasatake YAMATO 		parsePackage (token);
10273ae02089SMasatake YAMATO 		break;
1028b431e6a2SMasatake YAMATO 	case KEYWORD_ARCHITECTURE:
1029b431e6a2SMasatake YAMATO 		parseArchitecture (token);
103094b3dc24SMasatake YAMATO 		break;
1031e9ce313eSMasatake YAMATO 	case KEYWORD_SIGNAL:
1032e9ce313eSMasatake YAMATO 		parseSignal (token, index);
1033e9ce313eSMasatake YAMATO 		break;
1034e4754670SMasatake YAMATO 	case KEYWORD_PROCESS:
1035e4754670SMasatake YAMATO 		parseProcess (token, label, index);
1036e4754670SMasatake YAMATO 		break;
103708722ce3SMasatake YAMATO 	case KEYWORD_VARIABLE:
103808722ce3SMasatake YAMATO 		parseVariable (token, index);
103908722ce3SMasatake YAMATO 		break;
1040d7cb3fdeSMasatake YAMATO 	case KEYWORD_ALIAS:
1041d7cb3fdeSMasatake YAMATO 		parseAlias (token, index);
1042d7cb3fdeSMasatake YAMATO 		break;
10433ae02089SMasatake YAMATO 	default:
1044e4754670SMasatake YAMATO 		if (isType (token, TOKEN_IDENTIFIER))
1045e4754670SMasatake YAMATO 			parseLabel (token, index);
10463ae02089SMasatake YAMATO 		break;
10473ae02089SMasatake YAMATO 	}
10483ae02089SMasatake YAMATO }
10493ae02089SMasatake YAMATO 
parseVhdlFile(tokenInfo * const token)10503ae02089SMasatake YAMATO static tokenType parseVhdlFile (tokenInfo * const token)
10513ae02089SMasatake YAMATO {
10523ae02089SMasatake YAMATO 	do
10533ae02089SMasatake YAMATO 	{
10543ae02089SMasatake YAMATO 		readToken (token);
1055e4754670SMasatake YAMATO 		parseKeywords (token, NULL, CORK_NIL);
10563ae02089SMasatake YAMATO 	} while (!isKeyword (token, KEYWORD_END) && !isType (token, TOKEN_EOF));
10573ae02089SMasatake YAMATO 	return token->type;
10583ae02089SMasatake YAMATO }
10593ae02089SMasatake YAMATO 
findVhdlTags(void)10603ae02089SMasatake YAMATO static void findVhdlTags (void)
10613ae02089SMasatake YAMATO {
10623ae02089SMasatake YAMATO 	tokenInfo *const token = newToken ();
10633ae02089SMasatake YAMATO 
10643ae02089SMasatake YAMATO 	while (parseVhdlFile (token) != TOKEN_EOF);
10653ae02089SMasatake YAMATO 
10663ae02089SMasatake YAMATO 	deleteToken (token);
10673ae02089SMasatake YAMATO }
10683ae02089SMasatake YAMATO 
VhdlParser(void)10693ae02089SMasatake YAMATO extern parserDefinition *VhdlParser (void)
10703ae02089SMasatake YAMATO {
10713ae02089SMasatake YAMATO 	static const char *const extensions[] = { "vhdl", "vhd", NULL };
10723ae02089SMasatake YAMATO 	parserDefinition *def = parserNew ("VHDL");
107309ae690fSMasatake YAMATO 	def->kindTable = VhdlKinds;
10743db72c21SMasatake YAMATO 	def->kindCount = ARRAY_SIZE (VhdlKinds);
10753ae02089SMasatake YAMATO 	def->extensions = extensions;
10763ae02089SMasatake YAMATO 	def->parser = findVhdlTags;
10773ae02089SMasatake YAMATO 	def->initialize = initialize;
1078c379c5d2SMasatake YAMATO 	def->keywordTable = VhdlKeywordTable;
10793db72c21SMasatake YAMATO 	def->keywordCount = ARRAY_SIZE (VhdlKeywordTable);
1080a973df1dSMasatake YAMATO 	def->fieldTable = VhdlFields;
1081a973df1dSMasatake YAMATO 	def->fieldCount = ARRAY_SIZE (VhdlFields);
1082c02bf7b2SMasatake YAMATO 	def->useCork = CORK_QUEUE|CORK_SYMTAB;
10833ae02089SMasatake YAMATO 	return def;
10843ae02089SMasatake YAMATO }
1085