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 } |
