1 /****************************************************************************
2     Copyright (C) 1987-2015 by Jeffery P. Hansen
3 
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License along
15     with this program; if not, write to the Free Software Foundation, Inc.,
16     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 ****************************************************************************/
18 #include <unistd.h>
19 #include <string.h>
20 #include <ctype.h>
21 #include <stdio.h>
22 #include "config.h"
23 #include "yybasic.h"
24 #include "vgrammar.h"
25 #include "vparser.h"
26 #include "ycmalloc.h"
27 
28 #define STRMAX 8192
29 
30 extern struct lex_keywordentry lex_verilog_words[];
31 extern int lex_verilog_num;
32 extern struct lex_keywordentry lex_anotate_words[];
33 extern int lex_anotate_num;
34 extern struct lex_keywordentry lex_delay_words[];
35 extern int lex_delay_num;
36 
37 static int default_module_type = HDLMODULE;
38 static int current_module_type = HDLMODULE;
39 
40 typedef void *Encoder;
41 size_t recodeText(Encoder *encoder, char *toString,int len, const char *fromString);
42 extern Encoder *parserEncoder;
43 
44 /*****************************************************************************
45  *
46  * List of all Verilog reserved words.  These are used by the ycIsKW() function
47  * to indicate these names should not be used as identifiers in user circuits.
48  *
49  *****************************************************************************/
50 struct lex_keywordentry lex_reserved_words[] = {
51   {"always",1},
52   {"and",1},
53   {"assign",1},
54   {"attribute",1},
55   {"begin",1},
56   {"buf",1},
57   {"bufif0",1},
58   {"bufif1",1},
59   {"case",1},
60   {"casex",1},
61   {"casez",1},
62   {"cmos",1},
63   {"deassign",1},
64   {"default",1},
65   {"defparam",1},
66   {"disable",1},
67   {"edge",1},
68   {"else",1},
69   {"end",1},
70   {"endattribute",1},
71   {"endcase",1},
72   {"endfunction",1},
73   {"endmodule",1},
74   {"endprimitive",1},
75   {"endspecify",1},
76   {"endtable",1},
77   {"endtask",1},
78   {"event",1},
79   {"for",1},
80   {"force",1},
81   {"forever",1},
82   {"fork",1},
83   {"function",1},
84   {"highz0",1},
85   {"highz1",1},
86   {"if",1},
87   {"ifnone",1},
88   {"initial",1},
89   {"inout",1},
90   {"input",1},
91   {"integer",1},
92   {"join",1},
93   {"large",1},
94   {"medium",1},
95   {"module",1},
96   {"macromodule",1},
97   {"nand",1},
98   {"negedge",1},
99   {"nmos",1},
100   {"nor",1},
101   {"not",1},
102   {"notif0",1},
103   {"notif1",1},
104   {"or",1},
105   {"output",1},
106   {"parameter",1},
107   {"pmos",1},
108   {"posedge",1},
109   {"primitive",1},
110   {"pull0",1},
111   {"pull1",1},
112   {"pulldown",1},
113   {"pullup",1},
114   {"rcmos",1},
115   {"real",1},
116   {"realtime",1},
117   {"reg",1},
118   {"release",1},
119   {"repeat",1},
120   {"rnmos",1},
121   {"rpmos",1},
122   {"rtran",1},
123   {"rtranif0",1},
124   {"rtranif1",1},
125   {"scalared",1},
126   {"signed",1},
127   {"small",1},
128   {"specify",1},
129   {"specparam",1},
130   {"strength",1},
131   {"strong0",1},
132   {"strong1",1},
133   {"supply0",1},
134   {"supply1",1},
135   {"table",1},
136   {"task",1},
137   {"time",1},
138   {"tran",1},
139   {"tranif0",1},
140   {"tranif1",1},
141   {"tri",1},
142   {"tri0",1},
143   {"tri1",1},
144   {"triand",1},
145   {"trior",1},
146   {"trireg",1},
147   {"unsigned",1},
148   {"vectored",1},
149   {"wait",1},
150   {"wand",1},
151   {"weak0",1},
152   {"weak1",1},
153   {"while",1},
154   {"wire",1},
155   {"wor",1},
156   {"xnor",1},
157   {"xor",1},
158 };
159 
160 int lex_reserved_num = sizeof(lex_reserved_words)/sizeof(lex_reserved_words[0]);
161 
162 int nativeVerilog = 0;
163 
ycCheckHdlLine(char * s)164 int ycCheckHdlLine(char *s)
165 {
166   char *p;
167 
168   /*
169    * Trim trailing newline.
170    */
171   p = strrchr(s,'\n');
172   if (p) *p = 0;
173 
174   if (strstr(s,"//: /builtinEnd") != 0) {
175     ycSetModuleType(XMODULE);
176     return END;
177   }
178 
179   if (strstr(s,"//: endscript") != 0) {
180     return END;
181   }
182 
183   /*
184    * If this line has a '//: /netlistEnd' or '//: /hdlEnd' on it, treat this as
185    * the end of a new-style text segment.  If the line has 'endmodule' on it,
186    * treat it as the end of a native verilog module.
187    */
188   if (nativeVerilog) {
189     if (strstr(s,"endmodule") != 0)
190       return ENDMODULE;
191   } else {
192     if (strstr(s,"//: /netlistEnd") != 0 || strstr(s,"//: /hdlEnd") != 0) {
193       ycSetModuleType(XMODULE);
194       return END;
195     }
196   }
197 
198 
199 
200   yylval.S = yc_strdup(s);
201   return HDLLINE;
202 }
203 
204 
ycKeyCmp(const char * S1,const char * S2)205 int ycKeyCmp(const char *S1,const char *S2)
206 {
207   for (;*S1;S1++,S2++) {
208     int C1 = islower(*S1) ? toupper(*S1) : *S1;
209     int C2 = islower(*S2) ? toupper(*S2) : *S2;
210     if (C1 != C2) return (C1 < C2) ? -1 : 1;
211   }
212   return *S2 ? -1 : 0;
213 }
214 
ycLookup(char * Tok,struct lex_keywordentry * low,int len)215 int ycLookup(char *Tok,struct lex_keywordentry *low,int len)
216 {
217   struct lex_keywordentry *high = low+len-1;
218   struct lex_keywordentry *K;
219 
220   while (low <= high) {
221     K = low + (high-low)/2;
222     switch (ycKeyCmp(K->Keyword,Tok)) {
223     case  0 :
224       return K->Value;
225     case -1 :
226       low = K + 1;
227       break;
228     case  1 :
229       high = K - 1;
230       break;
231     }
232   }
233 
234   return -1;
235 }
236 
237 /*****************************************************************************
238  *
239  *
240  *
241  *****************************************************************************/
ycIsKW(char * Tok)242 int ycIsKW(char *Tok)
243 {
244   if (ycLookup(Tok,lex_anotate_words,lex_anotate_num) >= 0) return 1;
245   if (ycLookup(Tok,lex_verilog_words,lex_verilog_num) >= 0) return 1;
246   if (ycLookup(Tok,lex_reserved_words,lex_reserved_num) >= 0) return 1;
247   return 0;
248 }
249 
250 /*
251     Parse a "literal-like" token.  If it is in a keyword table, return the
252     token for that keyword, otherwise treat it as a literal.
253 */
ycLiteral(char * Tok,struct lex_keywordentry * low,int len)254 int ycLiteral(char *Tok,struct lex_keywordentry *low,int len)
255 {
256   int t;
257 
258   if (!Tok) Tok = "?";
259   yylval.S = "???";
260 
261   t = ycLookup(Tok,low,len);
262   yylval.S = yc_strdup(Tok);
263 
264   /*
265    * Special case for module keywords
266    */
267   switch (t) {
268   case XMODULE :
269     t = current_module_type;
270     break;
271   case NETLISTBEGIN :
272     ycSetModuleType(NETMODULE);
273     break;
274   case HDLBEGIN :
275     ycSetModuleType(HDLMODULE);
276     break;
277   case END :
278     ycSetModuleType(XMODULE);
279     break;
280   }
281 
282   return t >= 0 ? t : LITERAL;
283 }
284 
ycString(char * s)285 int ycString(char *s)
286 {
287   char buf[STRMAX];
288   char buf2[STRMAX];
289   char *p;
290 
291   /*
292    * Copy string and remove quotes.
293    */
294   strcpy(buf,s+1);
295   buf[strlen(buf)-1] = 0;
296 
297   /*
298    * Remove any '\' characters that may have been used to quote a quote character.
299    */
300   for (p = buf;*p;p++)
301     if (*p == '\\' && p[1]) {
302       memmove(p,p+1,strlen(p+1)+1);
303       p++;
304     }
305 
306   /*
307    * Translate the string from the file coding system.
308    */
309   recodeText(parserEncoder, buf2, STRMAX, buf);
310 
311   /*
312    * Set resulting string
313    */
314   yylval.S = yc_strdup(buf2);
315 
316   return STRING;
317 }
318 
yywrap()319 int yywrap()
320 {
321   return 1;
322 }
323 
ycSetDefaultModuleType(int modType)324 void ycSetDefaultModuleType(int modType)
325 {
326   default_module_type = modType;
327   current_module_type = modType;
328 }
329 
ycSetModuleType(int modType)330 void ycSetModuleType(int modType)
331 {
332   if (modType == XMODULE)
333     current_module_type = default_module_type;
334   else
335     current_module_type = modType;
336 }
337 
338