My Project  0.0.16
QUCS Mapping
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
syntax.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  syntax.cpp
3  ------------
4  begin : Sat Mar 11 2006
5  copyright : (C) 2006 by Michael Margraf
6  email : michael.margraf@alumni.tu-berlin.de
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 // *****************************************************************
19 // ********** **********
20 // ********** The class that do the syntax highlighting **********
21 // ********** **********
22 // *****************************************************************
23 
24 #include <qsyntaxhighlighter.h>
25 
26 #include "textdoc.h"
27 #include "syntax.h"
28 #include "main.h"
29 
31  : QSyntaxHighlighter(textEdit)
32 {
33  Doc = textEdit;
34  language = LANG_NONE;
35 }
36 
38 {
39 }
40 
41 // ---------------------------------------------------
43 {
44  language = lang;
45 }
46 
47 // ---------------------------------------------------
48 int SyntaxHighlighter::highlightParagraph(const QString& text, int state)
49 {
50  QChar c;
51  bool isFloat=false;
52  int iString=-1, iWord=-1, iNumber=-1, iExpo=-1, i=0, iComment=-1;
53  QFont font = Doc->TextFont;
54  font.setPointSize((int)Doc->Scale);
55  setFormat(0, text.length(), font, QPen::black);
56 
57  if (state < 0)
58  state = STATE_NONE;
59  if (state >= STATE_COMMENT)
60  iComment = 0;
61 
62  for(c = text.at(i); !c.isNull(); c = text.at(++i)) {
63  // ----- current text is a comment ---------------------------
64  if (iComment >= 0) {
65  setFormat (iComment, i-iComment+1, QucsSettings.Comment);
66  if (i > 0 && c == ')' && text.at (i-1) == '*') {
67  if (--state < STATE_COMMENT) {
68  state = STATE_NONE;
69  iComment = -1;
70  }
71  }
72  }
73  // ----- current text is a string ----------------------------
74  else if(iString >= 0) {
75  setFormat(iString, i-iString+1, QucsSettings.String);
76  if (language == LANG_OCTAVE)
77  if(c == '\'')
78  iString = -1;
79  if(c == '"')
80  iString = -1;
81  continue;
82  }
83  // ----- word that might become a reserved word --------------
84  else if(iWord >= 0) {
85  if(c.isLetterOrNumber())
86  continue;
87  if(c == '_')
88  continue;
89  do {
90  if(iWord > 0)
91  if(text.at(iWord-1) == '\'') {
92  markAttribute(text, iWord, i-iWord);
93  break;
94  }
95  markWord(text, iWord, i-iWord);
96  } while(false);
97  iWord = -1;
98  }
99  // ----- integer or floating point number --------------
100  else if(iNumber >= 0) {
101  if(c.isNumber())
102  continue;
103  if(c == '.') {
104  if(iExpo < 0) {
105  if(isFloat)
106  iNumber = -1;
107  isFloat = true;
108  }
109  else
110  iNumber = -1;
111  continue;
112  }
113  if((c == 'e') || (c == 'E')) {
114  if(iExpo < 0) {
115  iExpo = i;
116  isFloat = true;
117  }
118  else
119  iNumber = -1;
120  continue;
121  }
122  if((c == '-') || (c == '+')) {
123  if((iExpo+1) == i)
124  continue;
125  }
126  if(c != '_')
127  if(!c.isLetter()) {
128  if(isFloat)
129  setFormat(iNumber, i-iNumber, QucsSettings.Real);
130  else
131  setFormat(iNumber, i-iNumber, QucsSettings.Integer);
132  }
133  iNumber = -1;
134  }
135  // ----- maybe a VHDL comment -------------------------------
136  else if(language == LANG_VHDL && c == '-') {
137  if(i > 0)
138  if(text.at(i-1) == '-') { // VHDL comment starts with --
139  setFormat(i-1, text.length()-i, QucsSettings.Comment);
140  return state;
141  }
142  continue;
143  }
144  // ----- maybe a Verilog comment -------------------------------
145  else if((language == LANG_VERILOG || language == LANG_VERILOGA)
146  && c == '/') {
147  if(i > 0)
148  if(text.at(i-1) == '/') { // Verilog comment starts with //
149  setFormat(i-1, text.length()-i, QucsSettings.Comment);
150  return state;
151  }
152  continue;
153  }
154  // ----- maybe a Octave comment -------------------------------
155  else if((language == LANG_OCTAVE) && (c == '%' || c == '#')) {
156  setFormat(i, text.length()-i+1, QucsSettings.Comment);
157  return state;
158  }
159  // ----- no special syntax yet (or anymore) --------------
160  else {
161  if((language == LANG_VERILOG || language == LANG_VERILOGA)
162  && c == '`' && text.at(i+1).isLetter())
163  iWord = i;
164  else if((language == LANG_VERILOG || language == LANG_VERILOGA)
165  && c == '$' && text.at(i+1).isLetter())
166  iWord = i;
167  else if(c.isLetter())
168  iWord = i; // start a word
169  else if(c.isNumber()) {
170  iExpo = -1;
171  iNumber = i; // start a number
172  isFloat = false;
173  c = text.at(i-1);
174 /* if((c == '-') || (c == '+')) // include sign into number
175  iNumber--;*/
176  }
177  }
178 
179  if (state < STATE_COMMENT) {
180  if(c == '\'' && language != LANG_OCTAVE) {
181  if(i > 1)
182  if(text.at(i-2) == '\'')
183  setFormat(i-2, 3, QucsSettings.Character);
184  }
185  else if(c == '"' || (c == '\'' && language == LANG_OCTAVE))
186  iString = i;
187  }
188  if ((language == LANG_VERILOG || language == LANG_VERILOGA)
189  && i > 0 && c == '*' && text.at(i-1) == '(') {
190  if (state >= STATE_COMMENT) state++;
191  else state = STATE_COMMENT;
192  iComment = i-1;
193  }
194  }
195 
196  return state;
197 }
198 
199 // ---------------------------------------------------
200 typedef const char* pChar;
201 typedef const char** ppChar;
202 
203 // ---------------------------------------------------
204 // reserved VHDL words in alphabetical order
205 pChar VHD_List_A[] = {"abs", "access", "after", "alias", "all", "and",
206  "architecture", "array", "assert", "attribute", 0};
207 pChar VHD_List_B[] = {"begin", "block", "body", "buffer", "bus", 0};
208 pChar VHD_List_C[] = {"case", "component", "configuration", "constant", 0};
209 pChar VHD_List_D[] = {"disconnect", "downto", 0};
210 pChar VHD_List_E[] = {"else", "elsif", "end", "entity", "exit", 0};
211 pChar VHD_List_F[] = {"file", "for", "function", 0};
212 pChar VHD_List_G[] = {"generate", "generic", "group", "guarded", 0};
213 pChar VHD_List_I[] = {"if", "impure", "in", "inertial", "inout", "is", 0};
214 pChar VHD_List_L[] = {"label", "library", "linkage", "literal", "loop", 0};
215 pChar VHD_List_M[] = {"map", "mod", 0};
216 pChar VHD_List_N[] = {"nand", "new", "next", "nor", "not", "null", 0};
217 pChar VHD_List_O[] = {"of", "on", "open", "or", "others", "out", 0};
218 pChar VHD_List_P[] = {"package", "port", "postponed", "procedure", "process",
219  "pure", 0};
220 pChar VHD_List_R[] = {"range", "record", "register", "reject", "rem", "report",
221  "return", "rol", "ror", 0};
222 pChar VHD_List_S[] = {"select", "severity", "shared", "signal", "sla", "sll",
223  "sra", "srl", "subtype", 0};
224 pChar VHD_List_T[] = {"then", "to", "transport", "type", 0};
225 pChar VHD_List_U[] = {"unaffected", "units", "until", "use", 0};
226 pChar VHD_List_V[] = {"variable", 0};
227 pChar VHD_List_W[] = {"wait", "when", "while", "with", 0};
228 pChar VHD_List_X[] = {"xnor", "xor", 0};
229 
234  0, 0, (ppChar)&VHD_List_L,
239  0, 0};
240 
242  {"fs", "ps", "ns", "us", "ms", "sec", "min", "hr", 0};
243 
245  "bit", "bit_vector", "boolean", "std_logic", "std_logic_vector",
246  "std_ulogic", "std_ulogic_vector", "signed", "unsigned", "integer",
247  "real", "time", "character", "natural", 0};
248 
249 // ---------------------------------------------------
250 // reserved Verilog-HDL words in alphabetical order
251 pChar V_List_A[] = {"always", "and", "assign", "attribute", 0};
252 pChar V_List_B[] = {"begin", "buf", "bufif0", "bufif1", 0};
253 pChar V_List_C[] = {"case", "casex", "casez", "cmos", 0};
254 pChar V_List_D[] = {"deassign", "default", "defparam", "disable", 0};
255 pChar V_List_E[] = {"edge", "else", "end", "endattribute", "endcase",
256  "endfunction", "endmodule", "endprimitive", "endspecify",
257  "endtable", "endtask", "event", 0};
258 pChar V_List_F[] = {"for", "force", "forever", "fork", "function", 0};
259 pChar V_List_H[] = {"highz0", "highz1", 0};
260 pChar V_List_I[] = {"if", "ifnone", "initial", "inout", "input", 0};
261 pChar V_List_J[] = {"join", 0};
262 pChar V_List_L[] = {"large", 0};
263 pChar V_List_M[] = {"medium", "module", "macromodule", 0};
264 pChar V_List_N[] = {"nand", "negedge", "nmos", "nor", "not", "notif0",
265  "notif1", 0};
266 pChar V_List_O[] = {"or", "output", 0};
267 pChar V_List_P[] = {"pmos", "posedge", "primitive", "pull0", "pull1",
268  "pulldown", "pullup", 0};
269 pChar V_List_R[] = {"rcmos", "release", "repeat",
270  "rnmos", "rpmos", "rtran", "rtranif0", "rtranif1", 0};
271 pChar V_List_S[] = {"scalared", "signed", "small", "specify", "strength",
272  "strong0", "strong1", 0};
273 pChar V_List_T[] = {"table", "task", "tran", "tranif0", "tranif1", 0};
274 pChar V_List_U[] = {"unsigned", 0};
275 pChar V_List_V[] = {"vectored", 0};
276 pChar V_List_W[] = {"wait", "weak0", "weak1", "while", 0};
277 pChar V_List_X[] = {"xnor", "xor", 0};
278 
286  0, 0};
287 
289  {"reset_all", "timescale", "define", "include", "ifdef", "else", "endif",
290  "celldefine", "endcelldefine", "default_nettype", "unconnected_drive",
291  "nounconnected_drive", "delay_mode_zero", "delay_mode_unit",
292  "delay_mode_path", "delay_mode_distributed", "uselib", 0};
293 
295  "reg", "integer", "time", "real", "realtime", "wire", "tri", "wor",
296  "trior", "wand", "triand", "tri0", "tri1", "supply0", "supply1", "trireg",
297  "parameter", "specparam", "event", 0};
298 
300  {"setup", "hold", "setuphold", "skew", "recovery", "period", "width",
301  "monitor", "display", "write", "strobe", "fopen", "fclose", "time",
302  "stime", "realtime", "timeformat", "printtimescale", "random", "readmemb",
303  "readmemh", "finish", "stop", 0};
304 
305 // ---------------------------------------------------
306 // reserved Verilog-A words in alphabetical order
307 pChar VA_List_A[] = {"abstol", "access", "analog", "ac_stim", "analysis", 0};
308 pChar VA_List_B[] = {"begin", "branch", "bound_step", 0};
309 pChar VA_List_C[] = {"case", 0};
310 pChar VA_List_D[] = {"discipline", "ddt_nature", "ddt", "delay",
311  "discontinuity", "default", 0 };
312 pChar VA_List_E[] = {"enddiscipline", "else", "end", "endnature", "exclude",
313  "endfunction", "endmodule", "electrical", "endcase", 0};
314 pChar VA_List_F[] = {"for", "flow", "from", "final_step", "flicker_noise",
315  "function", 0};
316 pChar VA_List_G[] = {"generate", "ground", 0};
317 pChar VA_List_I[] = {"if", "idt_nature", "inf", "idt", "initial_step",
318  "input", "inout", 0};
319 pChar VA_List_L[] = {"laplace_nd", "laplace_np", "laplace_zd", "laplace_zp",
320  "last_crossing", 0};
321 pChar VA_List_M[] = {"module", 0};
322 pChar VA_List_N[] = {"nature", "noise_table", 0};
323 pChar VA_List_P[] = {"potential", "parameter", 0};
324 pChar VA_List_S[] = {"slew", 0};
325 pChar VA_List_T[] = {"timer", "transition", 0};
326 pChar VA_List_U[] = {"units", 0};
327 pChar VA_List_W[] = {"white_noise", "while", 0};
328 pChar VA_List_Z[] = {"zi_nd", "zi_np", "zi_zd", "zi_zp", 0};
329 
331  {(ppChar)&VA_List_A, (ppChar)&VA_List_B, (ppChar)&VA_List_C,
332  (ppChar)&VA_List_D, (ppChar)&VA_List_E, (ppChar)&VA_List_F,
333  (ppChar)&VA_List_G, 0, (ppChar)&VA_List_I,
334  0, 0, (ppChar)&VA_List_L,
335  (ppChar)&VA_List_M, (ppChar)&VA_List_N, 0,
336  (ppChar)&VA_List_P, 0, 0,
337  (ppChar)&VA_List_S, (ppChar)&VA_List_T, (ppChar)&VA_List_U,
338  0, (ppChar)&VA_List_W, 0,
339  0, (ppChar)&VA_List_Z };
340 
342  {"T", "G", "M", "K", "m", "u", "n", "p", "f", "a", 0};
343 
345  {"define", "else", "undef", "ifdef", "endif", "include", "resetall", 0};
346 
348  "integer", "real", 0};
349 
351  {"realtime", "temperature", "vt", "display", "strobe", 0};
352 
353 // ---------------------------------------------------
354 // reserved Octave words in alphabetical order
355 pChar OCT_List_C[] = {"case", "catch", 0};
356 pChar OCT_List_E[] = {"else", "elseif", "end", "endfor", "endfunction",
357  "endif", "endswitch", "end_try_catch", "endwhile",
358  "end_unwind_protect", 0};
359 pChar OCT_List_F[] = {"for", "function", 0};
360 pChar OCT_List_I[] = {"if", 0};
361 pChar OCT_List_O[] = {"otherwise", 0};
362 pChar OCT_List_S[] = {"switch", 0};
363 pChar OCT_List_T[] = {"try", 0};
364 pChar OCT_List_U[] = {"unwind_protect", "unwind_protect_cleanup", 0};
365 pChar OCT_List_W[] = {"while", 0};
366 
368  {0, 0, (ppChar)&OCT_List_C,
369  0, (ppChar)&OCT_List_E, (ppChar)&OCT_List_F,
370  0, 0, (ppChar)&OCT_List_I,
371  0, 0, 0,
372  0, 0, (ppChar)&OCT_List_O,
373  0, 0, 0,
374  (ppChar)&OCT_List_S, (ppChar)&OCT_List_T, (ppChar)&OCT_List_U,
375  0, (ppChar)&OCT_List_W, 0,
376  0, 0};
377 
379  "inf", "nan", "pi", 0};
380 
382  {"plot", 0};
383 
384 // ---------------------------------------------------
385 void SyntaxHighlighter::markWord(const QString& text, int start, int len)
386 {
387  pChar *List;
388  // apply font
389  QFont newFont = Doc->TextFont;
390  newFont.setPointSize((int)Doc->Scale);
391 
392  // get word
393  QString Word = text.mid(start, len);
394 
395  // switch case sensitivity
396  switch (language) {
397  case LANG_VHDL:
398  Word = Word.lower();
399  break;
400  default:
401  break;
402  }
403 
404  // get index into wordlist
405  int idx = (int)(Word.at(0).latin1() - 'a');
406  if(idx >= 0 && idx <= 25) {
407 
408  // switch wordlist
409  switch (language) {
410  case LANG_VHDL:
411  List = VHD_WordList[idx];
412  break;
413  case LANG_VERILOG:
414  List = V_WordList[idx];
415  break;
416  case LANG_OCTAVE:
417  List = OCT_WordList[idx];
418  break;
419  default:
420  List = VA_WordList[idx];;
421  break;
422  }
423 
424  // mark reserved words
425  if(List)
426  for( ; *List != 0; List++)
427  if(Word == *List) {
428  newFont.setWeight(QFont::Bold);
429  setFormat(start, len, newFont);
430  return;
431  }
432  }
433 
434  // mark data types
435  switch (language) {
436  case LANG_VHDL:
437  List = VHD_List_DataTypes;
438  break;
439  case LANG_VERILOG:
440  List = V_List_DataTypes;
441  break;
442  case LANG_OCTAVE:
443  List = OCT_List_DataTypes;
444  break;
445  default:
446  List = VA_List_DataTypes;
447  break;
448  }
449  if(List)
450  for( ; *List != 0; List++)
451  if(Word == *List) {
452  setFormat(start, len, QucsSettings.Type);
453  return;
454  }
455 
456  // mark units
457  switch (language) {
458  case LANG_VHDL:
459  List = VHD_List_Units;
460  break;
461  case LANG_VERILOGA:
462  List = VA_List_Units;
463  break;
464  default:
465  List = 0;
466  break;
467  }
468  if(List)
469  for( ; *List != 0; List++)
470  if(Word == *List) {
471  newFont.setWeight(QFont::Bold);
472  setFormat(start, len, newFont, QucsSettings.Real);
473  return;
474  }
475 
476 
477  if (Word.at(0) == '`' || Word.at(0) == '$') {
478  Word = Word.mid(1);
479  // mark directives
480  switch (language) {
481  case LANG_VERILOG:
482  List = V_List_Directives;
483  break;
484  case LANG_VERILOGA:
485  List = VA_List_Directives;
486  break;
487  default:
488  List = 0;
489  break;
490  }
491  if(List)
492  for( ; *List != 0; List++)
493  if(Word == *List) {
494  newFont.setWeight(QFont::Bold);
495  setFormat(start, len, newFont, QucsSettings.Directive);
496  return;
497  }
498 
499  // mark special functions
500  switch (language) {
501  case LANG_VERILOG:
502  List = V_List_Functions;
503  break;
504  case LANG_VERILOGA:
505  List = VA_List_Functions;
506  break;
507  case LANG_OCTAVE:
508  List = OCT_List_Functions;
509  break;
510  default:
511  List = 0;
512  break;
513  }
514  if(List)
515  for( ; *List != 0; List++)
516  if(Word == *List) {
517  newFont.setWeight(QFont::Bold);
518  setFormat(start, len, newFont, QucsSettings.Task);
519  return;
520  }
521  }
522 }
523 
524 // ---------------------------------------------------
525 // reserved VHDL attributes in alphabetical order
526 pChar VHD_List_Attrib_A[] = {"active", "ascending", 0};
527 pChar VHD_List_Attrib_B[] = {"base", 0};
528 pChar VHD_List_Attrib_D[] = {"delayed", 0};
529 pChar VHD_List_Attrib_E[] = {"event", 0};
530 pChar VHD_List_Attrib_H[] = {"high", 0};
531 pChar VHD_List_Attrib_I[] = {"image", 0};
532 pChar VHD_List_Attrib_L[] = {"last_active", "last_event", "last_value", "left",
533  "leftof", "length", "low", 0};
534 pChar VHD_List_Attrib_P[] = {"pos", "pred", 0};
535 pChar VHD_List_Attrib_Q[] = {"quiet", 0};
536 pChar VHD_List_Attrib_R[] = {"range", "reverse_range", "right", "rightof", 0};
537 pChar VHD_List_Attrib_S[] = {"stable", "succ", 0};
538 pChar VHD_List_Attrib_T[] = {"transaction", 0};
539 pChar VHD_List_Attrib_V[] = {"val", "value", 0};
540 
542  {(ppChar)&VHD_List_Attrib_A, (ppChar)&VHD_List_Attrib_B, 0,
543  (ppChar)&VHD_List_Attrib_D, (ppChar)&VHD_List_Attrib_E, 0,
544  0, (ppChar)&VHD_List_Attrib_H, (ppChar)&VHD_List_Attrib_I,
545  0, 0, (ppChar)&VHD_List_Attrib_L, 0, 0, 0,
546  (ppChar)&VHD_List_Attrib_P, (ppChar)&VHD_List_Attrib_Q,
547  (ppChar)&VHD_List_Attrib_R, (ppChar)&VHD_List_Attrib_S,
548  (ppChar)&VHD_List_Attrib_T, 0, (ppChar)&VHD_List_Attrib_V};
549 
550 void SyntaxHighlighter::markAttribute(const QString& text, int start, int len)
551 {
552  QString Word = text.mid(start, len).lower();
553  int idx = (int)(Word.at(0).latin1() - 'a');
554  if(idx < 0 || idx > 22)
555  return;
556  pChar *List = VHD_Attribute_List[idx];
557 
558  if(List)
559  for(; *List != 0; List++)
560  if(Word == *List) {
561  setFormat(start-1, len+1, QucsSettings.Attribute);
562  return;
563  }
564 }