2 Star 8 Fork 1

小鱼干 / RainbowLexer

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
commander.c 18.27 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
#include "commander.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <limits.h>
typedef struct RainbowError
{
char *errorMsg;
char *errorDoc;
} RainbowError;
typedef struct queue
{
RainbowCommandToken *queue;
unsigned long long size;
unsigned long long rear;
unsigned long long front;
} Rainbowqueue;
static long long RainBowLexer_id_num = ID_NUM;
static long long RainBowLexer_id_var = ID_VAR;
static long long RainBowLexer_id_string = ID_STRING;
#define BUF_SIZE 1024
#define QUEUE_INIT_SIZE 512;
static Rainbowqueue RainbowLexer_Ret = {NULL, 0, 0, 0};
static RainbowError UndefineToken = {"Undefine token", "UNdefine Token ->"};
static RainbowError StringError = {"Expected \"", "can not match \""};
static RainbowError MallocError = {"fail malloc", "failed to alloc memory"};
#define RAINBOW_RAISE(ERROR) printf("ERROR:\n[%s]:%s\n", ERROR.errorMsg, ERROR.errorDoc);
#define WHITESPACE_SKIP(str) \
{ \
while (*str == ' ') \
str++; \
}
RainbowLexerPrivate(void) RainbowQueueINIT()
{
RainbowLexer_Ret.front = 0;
RainbowLexer_Ret.rear = 0;
RainbowLexer_Ret.size = QUEUE_INIT_SIZE;
RainbowLexer_Ret.queue = (RainbowCommandToken *)malloc(RainbowLexer_Ret.size * sizeof(RainbowCommandToken));
}
RainbowLexerPrivate(void) RainbowRetAdd(char *token, long long id)
{
// printf("[%s] with %ld\n",token,id);
if (id >= IGNORE_MIN && id <= IGNORE_MAX)
return;
if (RainbowLexer_Ret.front + 1 >= RainbowLexer_Ret.size)
{
while (RainbowLexer_Ret.front + 1 >= RainbowLexer_Ret.size)
RainbowLexer_Ret.size += RainbowLexer_Ret.size >> 1;
RainbowLexer_Ret.queue = (RainbowCommandToken *)realloc(RainbowLexer_Ret.queue, RainbowLexer_Ret.size * sizeof(RainbowCommandToken));
}
RainbowCommandToken *tokenElement = RainbowLexer_Ret.queue + RainbowLexer_Ret.front++;
size_t len = strlen(token);
tokenElement->id = id;
tokenElement->token = (char *)malloc((len + 1) * sizeof(char));
if (tokenElement->token == NULL)
{
RAINBOW_RAISE(MallocError);
printf("[TOKEN-MALLOC]\n");
getchar();
return;
}
for (size_t i = 0; i < len; i++)
{
tokenElement->token[i] = token[i];
}
tokenElement->token[len] = '\0';
}
RainbowLexerPrivate(long long) RainbowStatuSperatorMatch(const char *token);
RainbowLexerPrivate(long long) RainbowStatusCheekOfStaticWordValiditySp(const char *token);
RainbowLexerPrivate(long long) RainbowStatusCheekOfStaticWordValidity(const char *token);
RainbowLexerPrivate(int) GetStatusOfNum(char ch)
{
switch (ch)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return 4;
break;
case '-':
case '+':
return 1;
break;
case ' ':
return 0;
break;
case '.':
return 2;
break;
case 'e':
case 'E':
return 3;
break;
case '\0':
return 6;
break;
default:
return 5;
break;
}
}
RainbowLexerPrivate(int) RainbowStatusCheekNumValidity(const char *token) //用于检查一个字符串是否为合法数字表示
{
static int numStatuGra[10][7] = {
//-1为否 -2为小数 -3为整数 -4为科学计数
//blank signal . e 0 alphabet end
{0, 1, 2, -1, 8, -1, -1}, //begin:0
{-1, -1, 2, -1, 8, -1, -1}, //Signal:1
{-1, -1, -1, -1, 9, -1, -1}, //Dot [before num]:2
{-1, -1, 4, 5, 3, -1, -4}, //number[before E]:3
{7, -1, -1, 5, 9, -1, -2}, //Dot [after num]:4
{-1, 1, -1, -1, 6, -1, -1}, //e:5
{7, -1, -1, -1, 6, -1, -4}, //number[after e]:6
{7, -1, -1, -1, -1, -1, -5}, //blank:7
{7, -1, 9, 5, 8, -1, -3}, //number[before dot]:8
{7, -1, -1, 5, 9, -1, -2} //number[after dot]:9
};
int status = numStatuGra[0][GetStatusOfNum(*token++)];
while (status >= 0)
{
status = numStatuGra[status][GetStatusOfNum(*token++)];
}
return status;
}
RainbowLexerPrivate(int) GetStatusOfVarName(char ch)
{
if (ch >= '0' && ch <= '9')
return 2;
else if ((isalpha(ch)) || (ch == '_'))
return 1;
else if (ch == ' ')
return 0;
else if (ch == '\0')
return 3;
else
return 4;
}
RainbowLexerPrivate(int) RainbowStatusCheekVarNameValidity(const char *token)
{
static int varNameStatus[4][5] =
{
//whitespace , ch , num , end undefine
{0, 1, -1, -1, -1}, //start : 0
{3, 1, 2, -2, -1}, //ch : 1
{3, 1, 2, -2, -1}, //num:2
{3, -1, -1, -2, -1}, //whitespace : 3
};
int status = varNameStatus[0][GetStatusOfVarName(*token++)];
while (status >= 0)
{
status = varNameStatus[status][GetStatusOfVarName(*token++)];
}
return status;
}
RainbowLexerPrivate(int) ISescapeChar(char ch)
{
switch (ch)
{
case '\\':
case 't':
case 'b':
case 'n':
case '\"':
case '\'':
return 1;
break;
default:
return 0;
break;
}
}
RainbowLexerPrivate(char *) RainbowStatusCheekOfString(const char *token, char singleORdouble)
{
const char *ptr = token;
int len = 0;
while (ptr[len] != singleORdouble)
{
if (ptr[len] == '\n' || ptr[len] == '\0')
{
RAINBOW_RAISE(StringError);
return NULL;
}
else if (ptr[len] == '\\' && ISescapeChar(ptr[len + 1]))
len += 1;
len++;
}
char *string = (char *)malloc(len * sizeof(char));
for (size_t i = 0; i < len; i++)
{
string[i] = token[i];
}
string[len] = '\0';
return string;
}
RainbowLexerPublic(void) RainbowCommanderLex(const char *string)
{
/* 将string解析
并加入到ret列表中
*/
if (RainbowLexer_Ret.queue == NULL)
RainbowQueueINIT();
const char *strptr = string;
WHITESPACE_SKIP(strptr);
char buf[BUF_SIZE] = {'\0'};
size_t index = 0;
while (*strptr != '\0')
{
#if defined(DOUBLE_STRING_OPTION) || defined(SINGLE_STRING_OPTION)
#if !defined(DOUBLE_STRING_OPTION) && defined(SINGLE_STRING_OPTION)
if (*strptr == '\'')
#endif
#if defined(DOUBLE_STRING_OPTION) && !defined(SINGLE_STRING_OPTION)
if (*strptr == '\"')
#endif
#if defined(DOUBLE_STRING_OPTION) && defined(SINGLE_STRING_OPTION)
if (*strptr == '\"' || *strptr == '\'')
#endif
{
if (*buf != '\0')
{
long long id = 0;
id = RainbowStatusCheekOfStaticWordValidity(buf);
if (id >= 0)
RainbowRetAdd(buf, id);
else if (isalpha(*buf) && (ID_VAR != -1) && (RainbowStatusCheekVarNameValidity(buf) != -1))
RainbowRetAdd(buf, RainBowLexer_id_var);
else if (isdigit(*buf) && (ID_NUM != -1) && (RainbowStatusCheekNumValidity(buf) != -1))
RainbowRetAdd(buf, RainBowLexer_id_num);
else //错误处理
{
RAINBOW_RAISE(UndefineToken);
printf("%s\n", buf);
getchar();
putchar('\n');
}
}
#if !defined(DOUBLE_STRING_OPTION) && defined(SINGLE_STRING_OPTION)
char *string = RainbowStatusCheekOfString(strptr + 1, '\'');
#endif
#if defined(DOUBLE_STRING_OPTION) && !defined(SINGLE_STRING_OPTION)
char *string = RainbowStatusCheekOfString(strptr + 1, '\"');
#endif
#if defined(DOUBLE_STRING_OPTION) && defined(SINGLE_STRING_OPTION)
char *string = RainbowStatusCheekOfString(strptr + 1, *strptr == '\"' ? '\"' : '\'');
#endif
if (string == NULL)
return;
int len = strlen(string);
strptr += len + 2;
RainbowRetAdd(string, RainBowLexer_id_string);
continue;
}
#endif
int spRet = RainbowStatuSperatorMatch(strptr);
if (buf[0] == '\0' && spRet >= 0)
goto BUF_EMPTY_CASE_; //处理第一个字符是分隔符的情况
if (spRet >= 0)
{
long long id = 0;
id = RainbowStatusCheekOfStaticWordValidity(buf);
if (id >= 0)
RainbowRetAdd(buf, id);
else if (isalpha(*buf) && (ID_VAR != -1) && (RainbowStatusCheekVarNameValidity(buf) != -1))
RainbowRetAdd(buf, ID_VAR);
else if (isdigit(*buf) && (ID_NUM != -1) && (RainbowStatusCheekNumValidity(buf) != -1))
RainbowRetAdd(buf, ID_NUM);
else if (*buf == '\0')
goto BUF_EMPTY_CASE_; //用于处理多个连续分隔符的情况
else //错误处理
{
RAINBOW_RAISE(UndefineToken);
printf("%s\n", buf);
getchar();
putchar('\n');
}
BUF_EMPTY_CASE_:
memset(buf, '\0', BUF_SIZE);
index = 0;
for (size_t i = 0; i <= spRet; i++)
buf[i] = *strptr++;
RainbowRetAdd(buf, RainbowStatusCheekOfStaticWordValiditySp(buf));
memset(buf, '\0', BUF_SIZE);
}
else
buf[index++] = *strptr++;
}
if (*buf == '\0')
return; //buf已空 情况出现在最后一个字符是分隔符时
//清理buf
long long id = 0;
id = RainbowStatusCheekOfStaticWordValidity(buf);
if (id >= 0)
RainbowRetAdd(buf, id);
else if (isalpha(*buf) && (ID_VAR != -1) && (RainbowStatusCheekVarNameValidity(buf) != -1))
RainbowRetAdd(buf, ID_VAR);
else if (isdigit(*buf) && (ID_NUM != -1) && (RainbowStatusCheekNumValidity(buf) != -1))
RainbowRetAdd(buf, ID_NUM);
else //错误处理
{
RAINBOW_RAISE(UndefineToken);
printf("%s\n", buf);
putchar('\n');
}
}
RainbowLexerPublic(RainbowCommandToken *) RainbowCommanderNext()
{
if (RainbowLexer_Ret.rear == RainbowLexer_Ret.front)
return NULL;
else
return RainbowLexer_Ret.queue + RainbowLexer_Ret.rear++;
}
RainbowLexerPublic(void) RainbowCommanderQueueClear()
{
RainbowLexer_Ret.rear = 0;
int front = RainbowLexer_Ret.front - 1;
while (front >= 0)
{
free((RainbowLexer_Ret.queue + front)->token);
front--;
}
RainbowLexer_Ret.front = 0;
RainbowLexer_Ret.size = QUEUE_INIT_SIZE;
RainbowLexer_Ret.queue = (RainbowCommandToken *)realloc(RainbowLexer_Ret.queue, RainbowLexer_Ret.size);
}
RainbowLexerPrivate(long long) RainbowStatusCheekOfStaticWordValidity(const char *token)
{
switch (*token++)
{
case 'C':
{
switch (*token++)
{
case 'o':
{
switch (*token++)
{
case 'm':
{
switch (*token++)
{
case 'p':
{
switch (*token++)
{
case 'i':
{
switch (*token++)
case 'l':
{
switch (*token++)
{
case 'e':
{
if (*token == '\0')
return 8;
}
}
}
}
}
}
}
}
}
}
}
}
case 'D':
{
switch (*token++)
{
case 'e':
{
switch (*token++)
{
case 'l':
{
if (*token == '\0')
return 4;
}
default:
{
return -1;
break;
}
}
}
default:
{
return -1;
break;
}
}
}
case 'i':
{
switch (*token++)
{
case 'g':
{
switch (*token++)
{
case 'n':
{
switch (*token++)
{
case 'o':
{
switch (*token++)
{
case 'r':
{
switch (*token++)
{
case 'e':
{
if (*token == '\0')
return 13;
}
default:
{
return -1;
break;
}
}
}
default:
{
return -1;
break;
}
}
}
default:
{
return -1;
break;
}
}
}
default:
{
return -1;
break;
}
}
}
default:
{
return -1;
break;
}
}
}
case 'H':
{
switch (*token++)
{
case 'e':
{
switch (*token++)
{
case 'l':
{
switch (*token++)
{
case 'p':
{
if (*token == '\0')
return 6;
}
default:
{
return -1;
break;
}
}
}
default:
{
return -1;
break;
}
}
}
default:
{
return -1;
break;
}
}
}
case 'L':
{
switch (*token++)
{
case 'e':
{
switch (*token++)
{
case 'x':
{
if (*token == '\0')
return 3;
}
default:
{
return -1;
break;
}
}
}
default:
{
return -1;
break;
}
}
}
case 'Q':
{
switch (*token++)
{
case 'u':
{
switch (*token++)
{
case 'i':
{
switch (*token++)
{
case 't':
{
if (*token == '\0')
return 7;
}
default:
{
return -1;
break;
}
}
}
default:
{
return -1;
break;
}
}
}
default:
{
return -1;
break;
}
}
}
case 'S':
{
switch (*token++)
{
case 'h':
{
switch (*token++)
{
case 'o':
{
switch (*token++)
{
case 'w':
{
if (*token == '\0')
return 5;
}
default:
{
return -1;
break;
}
}
}
default:
{
return -1;
break;
}
}
}
default:
{
return -1;
break;
}
}
}
case 'r':
{
switch (*token++)
{
case 'e':
{
switch (*token++)
{
case 'g':
{
switch (*token++)
{
case 'S':
{
switch (*token++)
{
case 'w':
{
if (*token == '\0')
return 1;
}
case 'p':
{
if (*token == '\0')
return 2;
}
default:
{
return -1;
break;
}
}
}
default:
{
return -1;
break;
}
}
}
default:
{
return -1;
break;
}
}
}
default:
{
return -1;
break;
}
}
}
default:
return -1;
break;
}
}
RainbowLexerPrivate(long long) RainbowStatusCheekOfStaticWordValiditySp(const char *token)
{
switch (*token++)
{
case '\t':
{
return 2147473650;
break;
}
case '\n':
{
return 2147473648;
break;
}
case ' ':
{
return 2147473647;
break;
}
case '.':
{
return 2147473649;
break;
}
default:
return -1;
break;
}
}
RainbowLexerPrivate(long long) RainbowStatuSperatorMatch(const char *token)
{
long long id = RainbowStatusCheekOfStaticWordValiditySp(token);
switch (id)
{
case 2147473650:
{
return 0;
break;
}
case 2147473648:
{
return 0;
break;
}
case 2147473647:
{
return 0;
break;
}
case 2147473649:
{
return 0;
break;
}
default:
{
return -1;
break;
}
}
}
C
1
https://gitee.com/bupt_xyg/RainbowLexer.git
git@gitee.com:bupt_xyg/RainbowLexer.git
bupt_xyg
RainbowLexer
RainbowLexer
master

搜索帮助