FreeCalypso > hg > ueda-linux
comparison ueda/libuschem/rdschem_lex.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 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:cd92449fdb51 |
---|---|
1 /* | |
2 * token lexer for the schematic parser | |
3 */ | |
4 | |
5 #include <sys/types.h> | |
6 #include <stdio.h> | |
7 #include <ctype.h> | |
8 #include <strings.h> | |
9 #include "schemstruct.h" | |
10 #include "parserint.h" | |
11 | |
12 extern char *malloc(); | |
13 | |
14 extern struct schem_parse_state schem_parse_state; | |
15 | |
16 static | |
17 my_getchar() | |
18 { | |
19 register int c; | |
20 | |
21 c = getc(schem_parse_state.file); | |
22 if (c < 0) | |
23 return(c); | |
24 if (!isascii(c)) { | |
25 rdschem_error("non-ASCII character"); | |
26 exit(1); | |
27 } | |
28 if (iscntrl(c) && c != '\n' && c != '\t') { | |
29 rdschem_error("invalid control character"); | |
30 exit(1); | |
31 } | |
32 return(c); | |
33 } | |
34 | |
35 rdschem_token() | |
36 { | |
37 register int c; | |
38 register char *cp; | |
39 register int len; | |
40 static char delims[] = "\n\"%(),;={}"; | |
41 | |
42 if (c = schem_parse_state.pushback_token) { | |
43 schem_parse_state.pushback_token = 0; | |
44 return(c); | |
45 } | |
46 loop: c = my_getchar(); | |
47 switch (c) { | |
48 case EOF: | |
49 return(0); | |
50 case ' ': | |
51 case '\t': | |
52 goto loop; | |
53 case '"': | |
54 yylex_qstr(); | |
55 return(QSTRING); | |
56 case '%': | |
57 do | |
58 c = my_getchar(); | |
59 while (c != EOF && c != '\n'); | |
60 if (c == EOF) | |
61 return(0); | |
62 /* FALL THRU */ | |
63 case '\n': | |
64 schem_parse_state.lineno++; | |
65 goto loop; | |
66 case '(': | |
67 case ')': | |
68 case ',': | |
69 case ';': | |
70 case '=': | |
71 case '{': | |
72 case '}': | |
73 return(c); | |
74 } | |
75 cp = schem_parse_state.string; | |
76 *cp++ = c; | |
77 for (len = 1; ; ) { | |
78 c = my_getchar(); | |
79 if (c == EOF || c == ' ' || c == '\t') | |
80 break; | |
81 if (index(delims, c)) { | |
82 ungetc(c, schem_parse_state.file); | |
83 break; | |
84 } | |
85 if (len >= MAXSTRING) | |
86 rdschem_error("text token is too long"); | |
87 *cp++ = c; | |
88 len++; | |
89 } | |
90 *cp = '\0'; | |
91 return(STRING); | |
92 } | |
93 | |
94 static | |
95 yylex_qstr() | |
96 { | |
97 register int c; | |
98 register char *cp; | |
99 register int len; | |
100 | |
101 cp = schem_parse_state.string; | |
102 for (len = 0; ; ) { | |
103 c = my_getchar(); | |
104 if (c == EOF || c == '\n') | |
105 unterm: rdschem_error("unterminated quoted string"); | |
106 if (c == '"') | |
107 break; | |
108 if (c == '\\') { | |
109 c = my_getchar(); | |
110 if (c == EOF || c == '\n') | |
111 goto unterm; | |
112 } | |
113 if (len >= MAXSTRING) | |
114 rdschem_error("quoted string is too long"); | |
115 *cp++ = c; | |
116 len++; | |
117 } | |
118 *cp = '\0'; | |
119 } | |
120 | |
121 struct graphblock * | |
122 rdschem_graphblock(type) | |
123 { | |
124 struct graphblock *blk; | |
125 register int c, n; | |
126 | |
127 blk = (struct graphblock *) malloc(sizeof(struct graphblock)); | |
128 if (!blk) { | |
129 perror("malloc"); | |
130 exit(1); | |
131 } | |
132 blk->type = type; | |
133 blk->lineno = schem_parse_state.lineno; | |
134 c = my_getchar(); | |
135 if (c == EOF) | |
136 badeof: rdschem_error("EOF in a graphical block"); | |
137 if (c == '\n') | |
138 schem_parse_state.lineno++; | |
139 else | |
140 ungetc(c, schem_parse_state.file); | |
141 blk->offset = ftell(schem_parse_state.file); | |
142 | |
143 for (n = 0; n >= 0; ) { | |
144 c = my_getchar(); | |
145 switch (c) { | |
146 case EOF: | |
147 goto badeof; | |
148 case '%': | |
149 for (;;) { | |
150 c = my_getchar(); | |
151 if (c == EOF) | |
152 goto badeof; | |
153 if (c == '\n') | |
154 break; | |
155 } | |
156 /* FALL THRU */ | |
157 case '\n': | |
158 schem_parse_state.lineno++; | |
159 continue; | |
160 case '(': | |
161 skip_over_ps_string(); | |
162 continue; | |
163 case ')': | |
164 rdschem_error("unmatched \')\' in a graphical block"); | |
165 case '{': | |
166 n++; | |
167 continue; | |
168 case '}': | |
169 n--; | |
170 continue; | |
171 } | |
172 } | |
173 blk->length = ftell(schem_parse_state.file) - blk->offset - 1; | |
174 return(blk); | |
175 } | |
176 | |
177 static | |
178 skip_over_ps_string() | |
179 { | |
180 register int c, n; | |
181 | |
182 for (n = 1; n > 0; ) { | |
183 c = my_getchar(); | |
184 switch (c) { | |
185 case EOF: | |
186 badeof: rdschem_error("EOF in a PS string in a graphical block"); | |
187 case '\n': | |
188 schem_parse_state.lineno++; | |
189 continue; | |
190 case '(': | |
191 n++; | |
192 continue; | |
193 case ')': | |
194 n--; | |
195 continue; | |
196 case '\\': | |
197 c = my_getchar(); | |
198 if (c == EOF) | |
199 goto badeof; | |
200 if (c == '\n') | |
201 schem_parse_state.lineno++; | |
202 continue; | |
203 } | |
204 } | |
205 } |