FreeCalypso > hg > ueda-linux
view ueda/libuschem/rdschem_lex.c @ 8:640ba9db0e9d
ueda/sverp-bind/struct.h started
author | Space Falcon <falcon@ivan.Harhan.ORG> |
---|---|
date | Sat, 01 Aug 2015 03:57:31 +0000 |
parents | cd92449fdb51 |
children |
line wrap: on
line source
/* * token lexer for the schematic parser */ #include <sys/types.h> #include <stdio.h> #include <ctype.h> #include <strings.h> #include "schemstruct.h" #include "parserint.h" extern char *malloc(); extern struct schem_parse_state schem_parse_state; static my_getchar() { register int c; c = getc(schem_parse_state.file); if (c < 0) return(c); if (!isascii(c)) { rdschem_error("non-ASCII character"); exit(1); } if (iscntrl(c) && c != '\n' && c != '\t') { rdschem_error("invalid control character"); exit(1); } return(c); } rdschem_token() { register int c; register char *cp; register int len; static char delims[] = "\n\"%(),;={}"; if (c = schem_parse_state.pushback_token) { schem_parse_state.pushback_token = 0; return(c); } loop: c = my_getchar(); switch (c) { case EOF: return(0); case ' ': case '\t': goto loop; case '"': yylex_qstr(); return(QSTRING); case '%': do c = my_getchar(); while (c != EOF && c != '\n'); if (c == EOF) return(0); /* FALL THRU */ case '\n': schem_parse_state.lineno++; goto loop; case '(': case ')': case ',': case ';': case '=': case '{': case '}': return(c); } cp = schem_parse_state.string; *cp++ = c; for (len = 1; ; ) { c = my_getchar(); if (c == EOF || c == ' ' || c == '\t') break; if (index(delims, c)) { ungetc(c, schem_parse_state.file); break; } if (len >= MAXSTRING) rdschem_error("text token is too long"); *cp++ = c; len++; } *cp = '\0'; return(STRING); } static yylex_qstr() { register int c; register char *cp; register int len; cp = schem_parse_state.string; for (len = 0; ; ) { c = my_getchar(); if (c == EOF || c == '\n') unterm: rdschem_error("unterminated quoted string"); if (c == '"') break; if (c == '\\') { c = my_getchar(); if (c == EOF || c == '\n') goto unterm; } if (len >= MAXSTRING) rdschem_error("quoted string is too long"); *cp++ = c; len++; } *cp = '\0'; } struct graphblock * rdschem_graphblock(type) { struct graphblock *blk; register int c, n; blk = (struct graphblock *) malloc(sizeof(struct graphblock)); if (!blk) { perror("malloc"); exit(1); } blk->type = type; blk->lineno = schem_parse_state.lineno; c = my_getchar(); if (c == EOF) badeof: rdschem_error("EOF in a graphical block"); if (c == '\n') schem_parse_state.lineno++; else ungetc(c, schem_parse_state.file); blk->offset = ftell(schem_parse_state.file); for (n = 0; n >= 0; ) { c = my_getchar(); switch (c) { case EOF: goto badeof; case '%': for (;;) { c = my_getchar(); if (c == EOF) goto badeof; if (c == '\n') break; } /* FALL THRU */ case '\n': schem_parse_state.lineno++; continue; case '(': skip_over_ps_string(); continue; case ')': rdschem_error("unmatched \')\' in a graphical block"); case '{': n++; continue; case '}': n--; continue; } } blk->length = ftell(schem_parse_state.file) - blk->offset - 1; return(blk); } static skip_over_ps_string() { register int c, n; for (n = 1; n > 0; ) { c = my_getchar(); switch (c) { case EOF: badeof: rdschem_error("EOF in a PS string in a graphical block"); case '\n': schem_parse_state.lineno++; continue; case '(': n++; continue; case ')': n--; continue; case '\\': c = my_getchar(); if (c == EOF) goto badeof; if (c == '\n') schem_parse_state.lineno++; continue; } } }