FreeCalypso > hg > ueda-linux
comparison ueda/sverp/lexer.c @ 0:cd92449fdb51
initial import of ueda and ifctf-part-lib from ifctfvax CVS
author | Space Falcon <falcon@ivan.Harhan.ORG> |
---|---|
date | Mon, 20 Jul 2015 00:24:37 +0000 |
parents | |
children | 7b4f78fcca08 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:cd92449fdb51 |
---|---|
1 /* | |
2 * This module contains the lexer underlying the parser for the minimal | |
3 * subset of Verilog we grok; the same lexer will be used to read and parse | |
4 * the primitives definition file. | |
5 */ | |
6 | |
7 #include <ctype.h> | |
8 #include <stdio.h> | |
9 #include "lexer.h" | |
10 | |
11 char *parser_filename; | |
12 FILE *parser_readF; | |
13 int parser_lineno; | |
14 char parser_read_word[MAXWORD+1]; | |
15 int parser_read_number; | |
16 int pushback_token; | |
17 | |
18 void | |
19 parse_error(msg) | |
20 char *msg; | |
21 { | |
22 fprintf(stderr, "%s line %d: %s\n", parser_filename, parser_lineno, | |
23 msg); | |
24 exit(1); | |
25 } | |
26 | |
27 static | |
28 my_getchar() | |
29 { | |
30 register int c; | |
31 | |
32 c = getc(parser_readF); | |
33 if (c < 0) | |
34 return(c); | |
35 if (!isascii(c)) | |
36 parse_error("non-ASCII character"); | |
37 if (iscntrl(c) && c != '\n' && c != '\t') | |
38 parse_error("invalid control character"); | |
39 return(c); | |
40 } | |
41 | |
42 static void | |
43 handle_trad_comment() | |
44 { | |
45 register int c, flag; | |
46 | |
47 for (flag = 0; ; ) { | |
48 c = my_getchar(); | |
49 if (c < 0) | |
50 parse_error("/* comment ends in EOF"); | |
51 if (c == '\n') | |
52 parser_lineno++; | |
53 if (c == '/' && flag) | |
54 return; | |
55 flag = (c == '*'); | |
56 } | |
57 } | |
58 | |
59 static void | |
60 handle_line_comment() | |
61 { | |
62 register int c; | |
63 | |
64 for (;;) { | |
65 c = my_getchar(); | |
66 if (c < 0) | |
67 parse_error("// comment ends in EOF"); | |
68 if (c == '\n') { | |
69 parser_lineno++; | |
70 return; | |
71 } | |
72 } | |
73 } | |
74 | |
75 static void | |
76 handle_comment() | |
77 { | |
78 int c; | |
79 | |
80 c = my_getchar(); | |
81 switch (c) { | |
82 case '*': | |
83 /* traditional C comment style */ | |
84 handle_trad_comment(); | |
85 return; | |
86 case '/': | |
87 /* new-fangled double slash comment style */ | |
88 handle_line_comment(); | |
89 return; | |
90 default: | |
91 parse_error("character after '/' is not '*' or '/'"); | |
92 exit(1); | |
93 } | |
94 } | |
95 | |
96 static void | |
97 handle_num_token(first_digit) | |
98 { | |
99 register int c, n; | |
100 | |
101 parser_read_number = first_digit - '0'; | |
102 for (n = 1; ; n++) { | |
103 c = my_getchar(); | |
104 if (!isdigit(c)) | |
105 break; | |
106 parser_read_number *= 10; | |
107 parser_read_number += c - '0'; | |
108 } | |
109 if (c >= 0) { | |
110 if (isalpha(c) || c == '_') | |
111 parse_error( | |
112 "digits followed by letters: neither word nor number"); | |
113 ungetc(c, parser_readF); | |
114 } | |
115 if (n > MAXDIGITS) | |
116 parse_error("number is too long (MAXDIGITS exceeded)"); | |
117 } | |
118 | |
119 static void | |
120 handle_word_token(first_char) | |
121 { | |
122 register int c; | |
123 register char *cp; | |
124 register int len; | |
125 | |
126 cp = parser_read_word; | |
127 *cp++ = first_char; | |
128 for (len = 1; ; ) { | |
129 c = my_getchar(); | |
130 if (!isalnum(c) && c != '_' && c != '$') | |
131 break; | |
132 if (len >= MAXWORD) | |
133 parse_error("text token is too long"); | |
134 *cp++ = c; | |
135 len++; | |
136 } | |
137 *cp = '\0'; | |
138 if (c < 0) | |
139 return; | |
140 ungetc(c, parser_readF); | |
141 } | |
142 | |
143 static void | |
144 handle_qstr() | |
145 { | |
146 register int c; | |
147 register char *cp; | |
148 register int len; | |
149 | |
150 cp = parser_read_word; | |
151 for (len = 0; ; ) { | |
152 c = my_getchar(); | |
153 if (c == EOF || c == '\n') | |
154 unterm: parse_error("unterminated quoted string"); | |
155 if (c == '"') | |
156 break; | |
157 if (c == '\\') { | |
158 c = my_getchar(); | |
159 if (c == EOF || c == '\n') | |
160 goto unterm; | |
161 } | |
162 if (len >= MAXWORD) | |
163 parse_error("quoted string is too long"); | |
164 *cp++ = c; | |
165 len++; | |
166 } | |
167 *cp = '\0'; | |
168 } | |
169 | |
170 get_token() | |
171 { | |
172 register int c; | |
173 | |
174 if (c = pushback_token) { | |
175 pushback_token = 0; | |
176 return(c); | |
177 } | |
178 loop: c = my_getchar(); | |
179 switch (c) { | |
180 case EOF: | |
181 return(0); | |
182 case ' ': | |
183 case '\t': | |
184 goto loop; | |
185 case '\n': | |
186 parser_lineno++; | |
187 goto loop; | |
188 case '/': | |
189 handle_comment(); | |
190 goto loop; | |
191 case '(': | |
192 case ')': | |
193 case ',': | |
194 case '.': | |
195 case ':': | |
196 case ';': | |
197 case '[': | |
198 case ']': | |
199 return(c); | |
200 case '"': | |
201 handle_qstr(); | |
202 return(QSTRING); | |
203 } | |
204 if (isdigit(c)) { | |
205 handle_num_token(c); | |
206 return(NUMBER); | |
207 } | |
208 if (isalpha(c) || c == '_') { | |
209 handle_word_token(c); | |
210 return(WORD); | |
211 } | |
212 fprintf(stderr, "%s line %d: bad character \'%c\'\n", parser_filename, | |
213 parser_lineno, c); | |
214 exit(1); | |
215 } |