Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: ide/VerilogScanner.java


1   /* **********************************
2    File:ColorProvider.java
3    Author: Alec(alecu@kermit.cs.pub.ro)
4    Creted on Sun Jul  4 04:15:31 EDT 1999
5    Comments:  Part of the vIDE Project
6               Copyright 1999 the vIDE Team.
7   ***********************************/
8   
9   package ide;
10  
11  import java.awt.*;
12  import javax.swing.*;
13  import javax.swing.text.Segment;
14  /**
15   * Provides a color for each verilog token
16   */
17  
18  class VerilogScanner {
19  
20    /*
21     * don't forget to update the colors if you modify
22     * the indexes !
23     */
24    public static final int tokSLComm    = 0;
25    public static final int tokMLComm    = 1;
26    public static final int tokBinNr     = 2;
27    public static final int tokOctNr     = 3;
28    public static final int tokDecNr     = 4;
29    public static final int tokHexNr     = 5;
30    public static final int tokFloatNr   = 6;
31    public static final int tokKeyword   = 7;
32    public static final int tokPreproc   = 8;
33    public static final int tokSysTask   = 9;
34    public static final int tokSeparator = 10;
35    public static final int tokString    = 11;
36    public static final int tokStuff     = 12;
37  
38    int tokType;
39    int tokLen;
40    /**
41     * true if an open "/*" was found on this line
42     */
43    boolean openComment;
44    
45    char a[];
46    int start;
47    int stop;
48  
49    static String keywords[] = 
50    {
51      "always", "and", "assign",
52      
53      "begin", "buf", "bufif0", "bufif1",
54      
55      "case", "casex", "casez", "cmos",
56      
57      "deassign", "default", "defparam", "disable",
58      
59      "edge", "else", "end", "endcase", "endmodule", "endfunction",
60      "endprimitive", "endspecify", "endtable", "endtask", "event",
61      
62      "for", "force", "forever", "fork", "function",
63  
64      "highz0", "highz1",
65  
66      "if", "ifnone", "initial", "inout", "input", "integer",
67  
68      "join",
69  
70      "large",
71  
72      "macromodule", "medium", "module",
73  
74      "nand", "negedge", "nmos", "nor", "not", "notif0", "notif1",
75  
76      "or", "output",
77  
78      "parameter", "pmos", "posedge", "primitive", "pull0", "pull1",
79      "pullup", "pulldown",
80  
81      "rcmos", "real", "realtime", "reg", "release", "repeat", "rnmos",
82      "rpmos", "rtran", "rtranif0", "rtranif1",
83  
84      "scalared", "small", "specify", "specparam", "strong0", "strong1",
85      "supply1", "supply0",
86  
87      "table", "task", "time", "tran", "tranif0", "tranif1", "tri", "tri0",
88      "tri1", "triand", "trior", "trireg",
89  
90      "vectored",
91  
92      "wait", "wand", "weak0", "weak1", "while", "wire", "wor",
93  
94      "xnor", "xor"
95    };
96  
97  
98    static int kSize = keywords.length;
99  
100   /**
101    * Stores vectors alphabetically ordered. Each of these vectors
102    * contains all the keywords that start with the same letter.
103    * There should be no more than 30
104    * sorts of starting characters and 15 keywords starting with the same
105    * letter.
106    */
107   static char keys[][][] =new char[30][15][];
108 
109   /**
110    * How many keys are into each vector.
111    */
112   static int keysLengths[] = new int[30];  
113 
114   static {
115     /*
116      * fetches tthe keywords into keys, which is more
117      * a more reliable structure for the first
118      * matchloop into matchKeyword.
119      */
120     char [] buffer;
121     for(int i = 0; i < kSize; i++) {
122       buffer = keywords[i].toCharArray();
123       keys[buffer[0]-'a'][keysLengths[buffer[0] - 'a']++] = buffer;
124     }
125   }
126 
127   char [][] keyBuffer1, keyBuffer2;
128 
129   VerilogScanner () {
130     // 20 shoul be enough for holding all keywords
131     //that start with the same letter
132     keyBuffer1 = new char[20][];
133     keyBuffer2 = new char[20][];
134   }
135   
136   /**
137    * The pointer inside the current segment
138    */
139   int c;
140     
141   final void init(Segment s) {
142     a = s.array;
143     start = c = s.offset;
144     stop = start + s.count -1;
145   }
146 
147 
148   /**
149    * no more tears !
150    */
151   final boolean noMoreTokens() {
152     return c > stop;
153   }
154   
155   final boolean getToken() {
156     if (c > stop) return false;
157     //c <= stop:
158     int lastC = c;
159     char curChar = a[c];
160     /*System.out.println("current char: " + curChar + " hex: " +
161       Integer.toHexString(curChar));*/
162 
163     switch(curChar) {
164     case ' ':
165     case '\t':
166     case '\n':
167     case '\r':
168       tokType = tokStuff;
169       do {
170         c++;
171         if (c > stop) break;
172         curChar = a[c];
173       } while((curChar == ' ') || (curChar == '\t') ||
174                            (curChar == '\n') || (curChar == '\r'));
175         
176       break;
177     case '-':
178     case '+':
179     case ':':
180     case '*':
181     case '&':
182     case '<':
183     case '>':
184     case '!':
185     case '@':
186     case '#':
187     case '%':
188     case '^':
189     case '(':
190     case ')':
191     case '{':
192     case '}':
193     case '[':
194     case ']':
195     case '=':
196     case '|':
197     case ';':
198     case '.':
199     case ',':
200       tokType = tokSeparator;
201       c++;
202       break;
203     case '0':
204     case '1':
205     case '2':
206     case '3':
207     case '4':
208     case '5':
209     case '6':
210     case '7':
211     case '8':
212     case '9':
213     case '\'':
214       tokType = tokDecNr;
215       boolean cont;
216     loop1:
217       do {
218         c++;
219         cont = false;
220         if (c > stop) break;
221         curChar = a[c];
222         switch (curChar) {
223         case 'b':
224         case 'B':
225           tokType = tokDecNr;
226           cont = true;
227         case 'o':
228         case 'O':
229           tokType = tokOctNr;
230           cont = true;
231         case 'd':
232         case 'D':
233           cont = true;
234         case 'h':
235         case 'H':
236           tokType = tokHexNr;
237           cont = true;;
238         case 'e':
239         case 'E':
240           tokType = tokFloatNr;
241           cont = true;
242         }
243       } while(cont || isDigit(curChar));
244       break;
245     case '/':
246       c++;
247       if (c > stop) break;
248       curChar = a[c];
249       switch(curChar) {
250       case '/':
251         tokType = tokSLComm;
252         c = stop + 1;
253         break;
254       case '*':
255         tokType = tokMLComm;
256         openComment = false;
257         if (c < stop) {
258           c++;
259           char c1 = a[c];
260           do {
261             c++;
262             if (c > stop) {
263               openComment = true;
264               break;
265             }
266             curChar = c1;
267             c1 = a[c];
268           } while((c1 != '/') || (curChar != '*'));
269         } else openComment = true;
270         if (c <= stop) c++; //jump over last '/'
271         break;
272       default:
273         tokType = tokSeparator;
274       }
275       break;
276     case '`':
277       tokType = tokPreproc;
278       do {
279         c++;
280         if (c > stop) break;
281         curChar = a[c];
282       } while(isAlpha(curChar) || isDigit(curChar)
283                            || (curChar == '_'));
284       break;
285     case '\"':
286       tokType = tokString;
287       do {
288         c++;
289         if (c > stop) break;
290         curChar = a[c];
291       } while (curChar != '\"');
292       if (c <= stop) c++;
293       break;
294     case '$':
295       tokType = tokSysTask;
296       do {
297         c++;
298         if (c > stop) break;
299         curChar = a[c];
300       } while(isAlpha(curChar) || isDigit(curChar)
301                            || (curChar == '_'));
302       break;
303     default:
304       if (isKeywordConstituent(curChar))
305         matchKeyword();
306       else {
307         tokType = tokStuff;
308         c++;
309       }
310     }
311     /*System.out.println("token: [" + (new String(a, lastC, c-lastC )) +
312       "] lastC: " + lastC + " c: " + c + " type: " + tokType);*/
313     tokLen = c - lastC;
314     return true;
315   }
316 
317   void debug(String s) {
318     System.out.println(s);
319   }
320 
321   /**
322    * Checks whether there is a kwyword starting at tha current
323    * point or not and sets the tokType accordingly. The c pointer
324    * is advanced to the first unmatched character.
325    */
326   void matchKeyword() {
327     
328     char curChar = a[c];
329     int m = 0;
330     int charIndex = curChar - 'a';
331     int matches = keysLengths[charIndex], matches1;
332     char[][] tmp;
333   
334     tmp = keyBuffer1;
335     keyBuffer1 = keys[charIndex];
336     //debug("keymatch for [" + new String(a, c, stop - c + 1) + "]");
337     tokType = tokKeyword;
338     
339   matchloop:
340     while(isKeywordConstituent(curChar)) {
341       matches1 = 0;
342       for(int i = 0, j = 0;  i < matches; i++) {
343         if (m == keyBuffer1[i].length) continue;
344         if (curChar == keyBuffer1[i][m]) { //match
345           matches1++;
346           keyBuffer2[j++] = keyBuffer1[i];
347           //debug("matched: [" + new String(keyBuffer2[j-1]) + "]");
348         }
349       }
350       matches = matches1;
351       //rotate buffers:
352       keyBuffer1 = keyBuffer2;
353       keyBuffer2 = tmp;
354       tmp = keyBuffer1;
355       c++;
356       m++;
357       if (matches <= 1) break matchloop; //one or no match found
358       if (c > stop)  //nothing uniquely found till the end of the line
359         break;
360       curChar = a[c];
361     }
362 
363     if (matches == 1) {
364       //check the remaining characters :
365       int l = keyBuffer1[0].length;
366       while(m < l) {
367         if (c > stop) {
368           tokType = tokStuff;
369           return;
370         }
371         curChar = a[c];
372         if (curChar != keyBuffer1[0][m]) {
373           while(isAlpha1(curChar)) { //eat the rest
374             c++;
375             if (c > stop) break;
376             curChar = a[c];
377           }
378           tokType = tokStuff;
379           return;
380         }
381         m++;
382         c++;
383       }
384     } else {
385       if (matches > 1) {
386         //debug("m: " + m);
387         for (int i = 0; i < matches ; i++){
388           //debug("matching: [" + new String (keyBuffer1[i]) + "]");
389           if (keyBuffer1[i].length == m) {
390             //debug("matched keyword: [" + new String (keyBuffer1[i]) + "]");
391             tokType = tokKeyword;
392             return;
393           }
394         }
395         tokType = tokStuff;
396       } else {
397         while(isAlpha1(curChar)) { //eat the rest
398           c++;
399           if (c > stop) break;
400           curChar = a[c];
401         }
402         tokType = tokStuff; //0 matches
403       }
404     }
405   }
406 
407   /**
408    * @return true if the multiline comment
409    * ends on this line
410    */
411   boolean scanCommentEnd() {
412     char curChar1 = 0, curChar2;
413     do {
414        curChar2 = a[c++];
415        if ((curChar1 == '*') && (curChar2 == '/')) {
416          tokLen = c - start;
417          return true;
418        } else
419          curChar1 = curChar2;
420     } while (c <= stop);
421     tokLen = c - start;
422     return false;
423   }
424 
425   /**
426    * We could use isAlpha, but as u see from the keyword table,
427    * there appear only lower case words an tha characters '0' ad '1', so we
428    * can shrink the number of tests.
429    */
430   static final boolean isKeywordConstituent(char c) {
431     return ((c >= 'a') && (c <= 'z')) || (c == '0') || (c == '1');
432   }
433      
434   static final boolean isAlpha(char c) {
435     return ((c >= 'a') && (c <= 'z')) ||
436       ((c >= 'A') && (c <= 'Z')) || (c == '_');
437   }
438 
439   static final boolean isAlpha1(char c) {
440     return ((c >= 'a') && (c <= 'z')) ||
441       ((c >= '0') && (c <= '9')) ||
442       ((c >= 'A') && (c <= 'Z')) || (c == '_');
443   }
444 
445   static final boolean isDigit(char c) {
446     return (('0' <= c) && (c <= '9')) || (('A' <= c) && (c <= 'F'))
447       || (('a' <= c) && (c <= 'f')) || (c == '_') || (c == 'x') ||
448       (c == 'X') || (c == 'z') || (c == 'Z') || (c == '?');
449   }
450 
451   public static void main (String args[]) {
452     try {
453       UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
454     }
455     catch ( Exception e ) {
456       System.out.println ("bad: " + e);
457       e.printStackTrace();
458       System.exit(0);
459     }
460     UIManager.put(VerilogTextArea.uiClassID, "ide.VerilogTextUI");
461     
462     JFrame f = new JFrame();
463     VerilogTextArea vt = new VerilogTextArea();
464     f.setSize(new Dimension(100,100));
465     f.getContentPane().add(vt);
466     f.setVisible(true);
467   }
468 }
469 
470 
471