1
0
Files
2022-09-29 17:59:04 +03:00

197 lines
4.1 KiB
C

/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
#ident "@(#)localedef:colltbl/lex.c 1.1"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "colltbl.h"
#include "y.tab.h"
#define TRUE 1
#define FALSE 0
#define SKIPWHITE() while ((c = getchar()) == ' ' || c == '\t')
#define isodigit(d) (d >= '0' && d <= '7')
#define cktoklen(i) if (i >= BUFSIZ) error(PRERR, "token too long")
extern int Lineno;
static char buf[BUFSIZ];
static int type;
static int start = TRUE;
yylex()
{
int c;
int i, j;
int clen;
char ibuf[6];
again:
SKIPWHITE();
/* c now contains the first non-space character */
if (c == EOF)
return(c);
if (start) {
switch (c) {
case '#':
while ((c = getchar()) != '\n')
if (c == EOF)
return(EOF);
case '\n':
Lineno++;
goto again;
default:
i = 0;
buf[i++] = c;
while ((c = getchar()) != EOF && c != ' ' && c != '\t' && c != '\n') {
cktoklen(i);
buf[i++] = c;
}
ungetc(c, stdin);
buf[i] = '\0';
if (strcmp(buf, "codeset") == 0)
type = CODESET;
else if (strcmp(buf, "substitute") == 0)
type = SUBSTITUTE;
else if (strcmp(buf, "with") == 0)
type = WITH;
else if (strcmp(buf, "order") == 0)
type = ORDER;
else if (strcmp(buf, "is") == 0) {
type = IS;
} else
type = buf[0];
}
if (type != ORDER)
start = FALSE;
return(type);
}
if (type == CODESET) {
i = 0;
while (c != EOF && c != ' ' && c != '\t' && c != '\n') {
cktoklen(i);
buf[i++] = c;
c = getchar();
}
ungetc(c, stdin);
buf[i] = '\0';
yylval.sval = buf;
start = TRUE;
return(ID);
}
if (c == '"') {
clen = 0;
while ((c = getchar()) != '"') {
cktoklen(clen);
if (c == '\n' || c == EOF) {
buf[clen] = '\0';
error(NEWLINE, "string", buf);
Lineno++;
} else if (c == '\\') {
switch(c = getchar()) {
case '"': buf[clen++] = '"'; break;
case 'n': buf[clen++] = '\n'; break;
case 't': buf[clen++] = '\t'; break;
case 'f': buf[clen++] = '\f'; break;
case 'r': buf[clen++] = '\r'; break;
case 'b': buf[clen++] = '\b'; break;
case 'v': buf[clen++] = '\v'; break;
case 'a': buf[clen++] = '\7'; break;
case '\\': buf[clen++] = '\\'; break;
default:
if (isodigit(c)) {
j = 0;
do {
ibuf[j++] = c;
c = getchar();
} while (isodigit(c) && j<3);
ibuf[j] = '\0';
buf[clen++] = strtol(ibuf, (char **)NULL, 8);
ungetc(c, stdin);
} else
buf[clen++] = c;
break;
}
} else
buf[clen++] = c;
}
buf[clen] = '\0';
yylval.sval = strdup(buf);
start = TRUE;
return(STRING);
}
/* SYMBOL */
switch (c) {
case '(':
case '{':
case ')':
case '}':
return(c);
break;
case '\n':
Lineno++;
start = TRUE;
goto again;
case ';':
return(SEPARATOR);
default:
clen = 0;
do {
cktoklen(clen);
if (c == '\\') {
if ((c = getchar()) == '\n') {
Lineno++;
if (clen != 0) {
buf[clen] = '\0';
error(INVALID, "symbol", buf);
}
goto again;
}
ungetc(c, stdin);
c = '\\';
}
if (c == '\\' || c == '0') {
ibuf[0] = c;
if ((c = getchar()) != 'x' && c != 'X' && !isodigit(c)) {
buf[clen++] = ibuf[0];
ungetc(c, stdin);
continue;
}
ibuf[0] = '0';
ibuf[1] = c;
j = 2;
if (c == 'x' || c == 'X') {
while (isxdigit(c=getchar()) && j<5)
ibuf[j++] = c;
} else {
c = getchar();
while (isodigit(c) && j<5) {
ibuf[j++] = c;
c = getchar();
}
}
ungetc(c, stdin);
ibuf[j] = '\0';
buf[clen++] = strtol(ibuf, (char **)NULL, 0);
} else
buf[clen++] = c;
} while ((c = getchar()) != EOF && c != ';' && c != ')' && c != '}'
&& c != '\n');
ungetc(c, stdin);
buf[clen] = '\0';
if (strcmp(buf, "...") == 0)
return(ELLIPSES);
if (clen > 2) {
error(TOO_LONG, "symbol", buf);
clen = 2;
}
yylval.sval = buf;
return(SYMBOL);
}
}