📄 lex.c
字号:
#include "c.h"
#include <errno.h>
#define MAXTOKEN 32
int StatementCount = 0;
static int statementLevel;
static int readString(int unicodeFlag);
enum {
BLANK = 01, NEWLINE = 02, LETTER = 04,DIGIT = 010, HEX = 020, OTHER = 040};
static unsigned char map[256] = { /* 000 nul */ 0,
/* 001 soh */ 0,
/* 002 stx */ 0,
/* 003 etx */ 0,
/* 004 eot */ 0,
/* 005 enq */ 0,
/* 006 ack */ 0,
/* 007 bel */ 0,
/* 010 bs */ 0,
/* 011 ht */ BLANK,
/* 012 nl */ NEWLINE,
/* 013 vt */ BLANK,
/* 014 ff */ BLANK,
/* 015 cr */ 0,
/* 016 so */ 0,
/* 017 si */ 0,
/* 020 dle */ 0,
/* 021 dc1 */ 0,
/* 022 dc2 */ 0,
/* 023 dc3 */ 0,
/* 024 dc4 */ 0,
/* 025 nak */ 0,
/* 026 syn */ 0,
/* 027 etb */ 0,
/* 030 can */ 0,
/* 031 em */ 0,
/* 032 sub */ 0,
/* 033 esc */ 0,
/* 034 fs */ 0,
/* 035 gs */ 0,
/* 036 rs */ 0,
/* 037 us */ 0,
/* 040 sp */ BLANK,
/* 041 ! */ OTHER,
/* 042 " */ OTHER,
/* 043 # */ OTHER,
/* 044 $ */ 0,
/* 045 % */ OTHER,
/* 046 & */ OTHER,
/* 047 ' */ OTHER,
/* 050 ( */ OTHER,
/* 051 ) */ OTHER,
/* 052 * */ OTHER,
/* 053 + */ OTHER,
/* 054 , */ OTHER,
/* 055 - */ OTHER,
/* 056 . */ OTHER,
/* 057 / */ OTHER,
/* 060 0 */ DIGIT,
/* 061 1 */ DIGIT,
/* 062 2 */ DIGIT,
/* 063 3 */ DIGIT,
/* 064 4 */ DIGIT,
/* 065 5 */ DIGIT,
/* 066 6 */ DIGIT,
/* 067 7 */ DIGIT,
/* 070 8 */ DIGIT,
/* 071 9 */ DIGIT,
/* 072 : */ OTHER,
/* 073 ; */ OTHER,
/* 074 < */ OTHER,
/* 075 = */ OTHER,
/* 076 > */ OTHER,
/* 077 ? */ OTHER,
/* 100 @ */ 0,
/* 101 A */ LETTER | HEX,
/* 102 B */ LETTER | HEX,
/* 103 C */ LETTER | HEX,
/* 104 D */ LETTER | HEX,
/* 105 E */ LETTER | HEX,
/* 106 F */ LETTER | HEX,
/* 107 G */ LETTER,
/* 110 H */ LETTER,
/* 111 I */ LETTER,
/* 112 J */ LETTER,
/* 113 K */ LETTER,
/* 114 L */ LETTER,
/* 115 M */ LETTER,
/* 116 N */ LETTER,
/* 117 O */ LETTER,
/* 120 P */ LETTER,
/* 121 Q */ LETTER,
/* 122 R */ LETTER,
/* 123 S */ LETTER,
/* 124 T */ LETTER,
/* 125 U */ LETTER,
/* 126 V */ LETTER,
/* 127 W */ LETTER,
/* 130 X */ LETTER,
/* 131 Y */ LETTER,
/* 132 Z */ LETTER,
/* 133 [ */ OTHER,
/* 134 \ */ OTHER,
/* 135 ] */ OTHER,
/* 136 ^ */ OTHER,
/* 137 _ */ LETTER,
/* 140 ` */ 0,
/* 141 a */ LETTER | HEX,
/* 142 b */ LETTER | HEX,
/* 143 c */ LETTER | HEX,
/* 144 d */ LETTER | HEX,
/* 145 e */ LETTER | HEX,
/* 146 f */ LETTER | HEX,
/* 147 g */ LETTER,
/* 150 h */ LETTER,
/* 151 i */ LETTER,
/* 152 j */ LETTER,
/* 153 k */ LETTER,
/* 154 l */ LETTER,
/* 155 m */ LETTER,
/* 156 n */ LETTER,
/* 157 o */ LETTER,
/* 160 p */ LETTER,
/* 161 q */ LETTER,
/* 162 r */ LETTER,
/* 163 s */ LETTER,
/* 164 t */ LETTER,
/* 165 u */ LETTER,
/* 166 v */ LETTER,
/* 167 w */ LETTER,
/* 170 x */ LETTER,
/* 171 y */ LETTER,
/* 172 z */ LETTER,
/* 173 { */ OTHER,
/* 174 | */ OTHER,
/* 175 } */ OTHER,
/* 176 ~ */ OTHER,
/* 177 del */ OTHER,
/* 200 */ LETTER,
/* 130 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 135 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 140 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 145 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 150 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 155 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 160 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 165 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 170 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 175 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 180 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 185 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 190 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 195 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 205 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 210 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 215 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 220 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 225 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 230 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 235 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 240 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 245 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 250 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
/* 200 */ LETTER,
};
static struct symbol tval;
static int backslash ARGS((int q));
static Symbol fcon ARGS((void));
static Symbol icon ARGS((unsigned int, int, int));
static void ppnumber ARGS((char *));
Coordinate src; /* current source coordinate */
int t;
char *token; /* current token */
Symbol tsym; /* symbol table entry for current token */
static int doDeclSpec(void);
extern AddExportSymbol(char *);
/* asmargs - break out %name in string p, fill in argv, returned edited string */
static char *asmargs(Symbol p, Symbol argv[], int size)
{
int n = 0;
char *s1, *s2, str[MAXLINE];
if (p->type->size >= MAXLINE) {
error(StrTab[171]); // <asm string too long\n>
return "";
}
for (s2 = str, s1 = p->u.c.v.p; *s1;)
if ((*s2++ = *s1++) == '%' && *s1 && map[*s1] & LETTER) {
char *t = s1;
while (*t && map[*t] & (LETTER | DIGIT))
t++;
if ((argv[n] = lookup(stringn(s1, t - s1), identifiers))
&& argv[n]->sclass != TYPEDEF && argv[n]->sclass != ENUM) {
argv[n]->ref += refinc;
argv[n]->references++;
argv[n]->lastuse = StatementCount;
if (++n == size) {
error(StrTab[172]); // <too many variable references in asm string\n>
n = size - 1;
}
else {
*s2++ = n - 1;
s1 = t;
}
}
}
*s2 = 0;
argv[n] = 0;
return stringn(str, s2 - str);
}
static void assem(void)
{
if (Aflag >= 2)
warning(StrTab[173]); // <non-ANSI asm\n>
t = gettok();
if (t == '{') {
do {
t = gettok();
} while (t != '}');
return;
}
expect('(');
if (t == SCON) {
char *s;
Symbol *argv = (Symbol *) allocate(11 * sizeof(Symbol *), FUNC);
s = asmargs(tsym, argv, 11);
if (fname) {
walk(0, 0, 0);
code(Start); /* prevent unreachable code message */
code(Asm);
codelist->u.acode.code = s;
codelist->u.acode.argv = argv;
}
else
asmcode(s, argv);
t = gettok();
}
else
error(StrTab[174]); // <missing string constant in asm\n>
if (t != ')')
expect(')');
}
int gettok(void)
{
for (;;) {
register unsigned char *rcp = cp;
while (map[*rcp] & BLANK)
rcp++;
if (limit - rcp < MAXTOKEN) {
cp = rcp;
fillbuf();
rcp = cp;
}
src.file = file;
src.x = (char *) rcp - line;
src.y = lineno;
cp = rcp + 1;
switch (*rcp++) {
case '/':
if (*rcp == '*') {
int c = 0;
for (rcp++; *rcp != '/' || c != '*';)
if (map[*rcp] & NEWLINE) {
if (rcp < limit)
c = *rcp;
cp = rcp + 1;
nextline();
rcp = cp;
if (rcp == limit)
break;
}
else
c = *rcp++;
if (rcp < limit)
rcp++;
else
error(StrTab[175]); // <unclosed comment\n>
cp = rcp;
continue;
}
return '/';
case 'L':
if (*rcp == '\'') {
int t = gettok();
assert(t == ICON);
src.x--;
tval.type = unsignedshort;
tval.u.c.v.uc = (unsigned short) tval.u.c.v.i;
return t;
}
if (*rcp != '"')
goto id;
cp = rcp + 1;
return readString(1);
case '<':
if (*rcp == '=')
return cp++, LEQ;
if (*rcp == '<')
return cp++, LSHIFT;
return '<';
case '>':
if (*rcp == '=')
return cp++, GEQ;
if (*rcp == '>')
return cp++, RSHIFT;
return '>';
case '-':
if (*rcp == '>')
return cp++, DEREF;
if (*rcp == '-')
return cp++, DECR;
return '-';
case '=':
return *rcp == '=' ? cp++, EQL : '=';
case '!':
return *rcp == '=' ? cp++, NEQ : '!';
case '|':
return *rcp == '|' ? cp++, OROR : '|';
case '&':
return *rcp == '&' ? cp++, ANDAND : '&';
case '+':
return *rcp == '+' ? cp++, INCR : '+';
case ',':
case ':':
case '*':
case '~':
case '%':
case '^':
case '?':
case '[':
case ']':
case '(':
case ')':
return rcp[-1];
case ';':
return rcp[-1];
case '{':
statementLevel++;
return rcp[-1];
case '}':
if (statementLevel)
statementLevel--;
return rcp[-1];
case '\n':
case '\v':
case '\r':
case '\f':
nextline();
if (cp == limit) {
tsym = NULL;
return EOI;
}
continue;
case 'i':
if (rcp[0] == 'f'
&& !(map[rcp[1]] & (DIGIT | LETTER))) {
cp = rcp + 1;
return IF;
}
if (rcp[0] == 'n'
&& rcp[1] == 't'
&& !(map[rcp[2]] & (DIGIT | LETTER))) {
cp = rcp + 2;
tsym = inttype->u.sym;
return INT;
}
goto id;
case '_':
if (rcp[0] == 's' &&
rcp[1] == 't' &&
rcp[2] == 'd' &&
rcp[3] == 'c' &&
rcp[4] == 'a' &&
rcp[5] == 'l' &&
rcp[6] == 'l' &&
!(map[rcp[7]] & (DIGIT | LETTER))) {
cp = rcp + 7;
return STDCALL;
}
if (rcp[0] == 'a' &&
rcp[1] == 's' &&
rcp[2] == 'm' &&
!(map[rcp[3]] & (DIGIT | LETTER))) {
cp = rcp + 3;
assem();
return (gettok());
}
if (rcp[0] == '_' &&
rcp[1] == 't' &&
rcp[2] == 'r' &&
rcp[3] == 'y' &&
!(map[rcp[4]] & (DIGIT | LETTER))) {
cp = rcp + 4;
doTry();
return (gettok());
}
if (rcp[0] == '_') {
if (rcp[1] == 'e' &&
rcp[2] == 'x' &&
rcp[3] == 'c' &&
rcp[4] == 'e' &&
rcp[5] == 'p' &&
rcp[6] == 't' &&
!(map[rcp[7]] & (DIGIT | LETTER))) {
cp = rcp + 7;
doExcept();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -