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 }