File: verilog-lex.el

package info (click to toggle)
verilog-mode 20161124.fd230e6-2
  • links: PTS, VCS
  • area: main
  • in suites: buster, stretch
  • size: 3,764 kB
  • ctags: 5,143
  • sloc: lisp: 12,430; perl: 293; makefile: 146; sh: 35; fortran: 2
file content (161 lines) | stat: -rw-r--r-- 6,937 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
;;
;; Lexical analysis
;;

(defconst verilog-token-comma		?,      "Verilog-lex ','.")
(defconst verilog-token-semi		?;	"Verilog-lex ';'.")
(defconst verilog-token-equal		?=	"Verilog-lex '='.")
(defconst verilog-token-par		?(	"Verilog-lex '('.")
(defconst verilog-token-en		?)	"Verilog-lex ')'.")
(defconst verilog-token-bra		?{	"Verilog-lex '{'.")
(defconst verilog-token-ce		?}	"Verilog-lex '}'.")

;; Lexical tokens specific to verilog-lex-decl
(defconst verilog-token-ASSIGN		300	"Verilog-lex 'KEYWORD'.")
(defconst verilog-token-PARAMETER	306	"Verilog-lex 'KEYWORD'.")
(defconst verilog-token-SIGNED		307	"Verilog-lex 'KEYWORD'.")
(defconst verilog-token-bracketed	311	"Verilog-lex '[...]'; value is what's within brackets.")
(defconst verilog-token-decl-const	301	"Verilog-lex declare constant.")
(defconst verilog-token-decl-wire	302	"Verilog-lex declare wire.")
(defconst verilog-token-direction	303	"Verilog-lex directional.")
(defconst verilog-token-ignore-begin	304	"Verilog-lex block to ignore begin.")
(defconst verilog-token-ignore-end	305	"Verilog-lex block to ignore end.")
(defconst verilog-token-symbol		310	"Verilog-lex symbol.")
(defconst verilog-token-synth-enum	312	"Verilog-lex Synopsys enum token; value is name of enumeration.")
(defconst verilog-token-type		308	"Verilog-lex data type.")
(defconst verilog-token-keyword		313	"Verilog-lex generic keyword.")

(defconst verilog-lex-keywords
  '(
    ("assign"		verilog-token-ASSIGN)
    ("bit"		verilog-token-type)
    ("byte"		verilog-token-type)
    ("class"		verilog-token-ignore-begin)
    ("clocking"		verilog-token-ignore-begin)
    ("covergroup"	verilog-token-ignore-begin)
    ("endclass"		verilog-token-ignore-end)
    ("endclocking"	verilog-token-ignore-end)
    ("endfunction"	verilog-token-ignore-end)
    ("endgroup"		verilog-token-ignore-end)
    ("endproperty"	verilog-token-ignore-end)
    ("endsequence"	verilog-token-ignore-end)
    ("endtask"		verilog-token-ignore-end)
    ("function"		verilog-token-ignore-begin)
    ("genvar"		verilog-token-decl-const)
    ("inout"		verilog-token-direction)
    ("input"		verilog-token-direction)
    ("int"		verilog-token-type)
    ("integer"		verilog-token-type)
    ("localparam"	verilog-token-decl-const)
    ("logic"		verilog-token-type)
    ("longint"		verilog-token-type)
    ("output"		verilog-token-direction)
    ("parameter"	verilog-token-PARAMETER)
    ("property"		verilog-token-ignore-begin)
    ("randsequence"	verilog-token-ignore-begin)
    ("real"		verilog-token-type)
    ("reg"		verilog-token-type)
    ("sequence"		verilog-token-ignore-begin)
    ("shortint"		verilog-token-type)
    ("shortreal"	verilog-token-type)
    ("signed"		verilog-token-signing)
    ("supply"		verilog-token-decl-const)
    ("supply0"		verilog-token-decl-const)
    ("supply1"		verilog-token-decl-const)
    ("task"		verilog-token-ignore-begin)
    ("time"		verilog-token-type)
    ("tri"		verilog-token-decl-wire)
    ("tri0"		verilog-token-decl-wire)
    ("tri1"		verilog-token-decl-wire)
    ("triand"		verilog-token-decl-wire)
    ("trior"		verilog-token-decl-wire)
    ("trireg"		verilog-token-type)
    ("wand"		verilog-token-decl-wire)
    ("wire"		verilog-token-decl-wire)
    ("wor"		verilog-token-decl-wire)
    )
  "Map of keyword and token to return for `verilog-lex'.")

(defun verilog-lex (begin end for-decls)
  "Lexically analyze Verilog text between BEGIN to END into tokens.
With FOR-DECL true, parse only for declarations.  Returns list of
tokens, with each token a list of the text for that token and the
verilog-token-TYPE."
  (let ((functask 0)
	tokens token keywd ignore-next-symbol)
    (save-excursion
      (goto-char begin)
      (while (< (point) end)
	;;(if dbg (setq dbg (cons (format "Pt %s  Vec %s   Kwd'%s'\n" (point) vec keywd) dbg)))
	(cond
	 ;; For performance it's better if frequent cases are first
	 ((looking-at "//")
	  (when (looking-at "[^\n]*synopsys\\s +enum\\s +\\([a-zA-Z0-9_]+\\)")
	    (setq tokens (cons (list (match-string 1) verilog-token-synth-enum) tokens)))
	  (search-forward "\n"))
	 ((looking-at "/\\*")
	  (forward-char 2)
	  (when (looking-at "[^*]*synopsys\\s +enum\\s +\\([a-zA-Z0-9_]+\\)")
	    (setq tokens (cons (list (match-string 1) verilog-token-synth-enum) tokens)))
	  (or (search-forward "*/")
	      (error "%s: Unmatched /* */, at char %d" (verilog-point-text) (point))))
	 ((looking-at "(\\*")
	  (forward-char 2)
	  (or (looking-at "\\s-*)")   ; It's an "always @ (*)"
	      (search-forward "*)")
	      (error "%s: Unmatched (* *), at char %d" (verilog-point-text) (point))))
	 ((eq ?\" (following-char))
	  (or (re-search-forward "[^\\]\"" nil t)	;; don't forward-char first, since we look for a non backslash first
	      (error "%s: Unmatched quotes, at char %d" (verilog-point-text) (point))))
	 ;; []: Grab all text to ending ].  Probably should match bracket pairs and strip comments, but old version didn't
	 ((looking-at "\\[[^]]+\\]")
	  (goto-char (match-end 0))
	  (setq tokens (cons (list (match-string 0) verilog-token-bracketed) tokens)))
	 ;; Single character tokens we just pass through
	 ((looking-at "[;,=(){}]")
	  (setq tokens (cons (list (following-char) (following-char)) tokens))
	  (forward-char 1))
	 ;; Ifdef, ignore name of define
	 ((looking-at "`ifn?def\\>")
	  (goto-char (match-end 0))
	  (setq ignore-next-symbol t))
	 ;; Normal identifier
	 ((looking-at "[`a-zA-Z0-9_$]+")
	  (goto-char (match-end 0))
	  ;; buffer-substring is faster than match-string, and this is hot code.
	  (setq keywd (buffer-substring-no-properties (match-beginning 0) (match-end 0)))
	  (cond (ignore-next-symbol	;; preproc identifier after `ifdef
		 (setq ignore-next-symbol nil))
		((member keywd verilog-keywords)
		 (setq token (assoc keywd verilog-lex-keywords))
		 ;; Now you'll see why the token list has text first then the token number;
		 ;; we can just return the assoc result directly
		 (cond ((eq token verilog-token-ignore-begin)
			(setq functask (1+ functask)))
		       ((eq token verilog-token-ignore-end)
			(setq functask (1- functask)))
		       (token
			(setq tokens (cons token tokens)))
		       (t
			(setq tokens (cons (list keywd verilog-token-keyword) tokens)))))
		;; Must be typedef or symbol.  For speed, ignore if inside begin/end
		((and (eq functask 0)
		      (verilog-typedef-name-p keywd))
		   (setq tokens (cons (list keywd verilog-token-typedef) tokens)))
		;; Normal user symbol
		((eq functask 0)
		 (setq tokens (cons (list keywd verilog-token-symbol) tokens)))))
	 ;; Escaped identifier -- note we remember the \ if escaped
	 ((looking-at "\\\\[^ \t\n\f]+")
	  (goto-char (match-end 0))
	  (when (eq functask 0)
	    (setq tokens (cons (list (concat (match-string-no-properties 0) " ") ;; Escaped ID needs space at end
				     verilog-token-symbol)
			       tokens))))
	 ;; Default
	 (t
	  (forward-char 1)))
	;; End of parser while
	(skip-syntax-forward " "))
      tokens)))