a4_0018
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
* acl4のページ0018
-(by [[K]], 2026.04.23)
** (1) 概要
-a4_0018 は、 acl4v1 にとっての3番目のライブラリプログラ...
-提供される主な機能は、以下の通りです。
--(1-1)ファイルなどの文字列からトークンを切り出す Token0/...
--(1-2)VecChrを使ってスタック構造を作って読み書きする Vec...
--(1-3)かっこでくくられた構造を切り分ける parseArgs
--(1-4)Cの文字列リテラルで使われるエスケープシーケンスを...
-以下、それぞれについてもう少し詳しく説明します。
~
-(1-1)ファイルなどの文字列からトークンを切り出す Token0/T...
--プログラミング言語を作るなら、トークン繰り出し関数があ...
-(1-2)VecChrを使ってスタック構造を作って読み書きする VecC...
--Add が push で、Rmv が pop(pull) です。 x86 などのスタ...
-(1-3)かっこでくくられた構造を切り分ける parseArgs
--「(a,b+c,d-3)」みたいな文字列を、「a」「b+c」「d-3」に...
-(1-4)の文字列リテラルで使われるエスケープシーケンスをデ...
--\nとか\tなどをしかるべき文字コードに置換していきます。
** (2) デモ
** (3) ライブラリプログラム
#if (a_Version >= 1)
#define Token0 a_Token0
#define Token0Table a_Token0Table
#define Token0Table_ini a_Token0Table_ini
#define Token0_get a_Token0_get
#define Token1_get a_Token1_get
#define Token0_ini1 a_Token0_ini1
#endif
a_class(a_Token0Table) {
uint32_t *op[4];
unsigned char chrTyp[256];
// 0: 空白類.
// 1: 1文字記号.
// 2: 一般記号文字.
// 3: アルファベット/数字.
};
a_class(a_Token0) {
a_Token0Table *tbl;
const char *s, *s1;
unsigned char cTyp;
uint32_t c;
intptr_t len;
};
a_static int a_Token0Table_iniSub(uint32_t *op, const ch...
{
int i = 0;
for (;;) {
while (*s == ' ') s++;
if (*s == '\0') break;
if (s[1] <= ' ') { op[i++] = s[0]; ...
if (s[2] <= ' ') { op[i++] = s[0] | s[1] << 8; ...
if (s[3] <= ' ') { op[i++] = s[0] | s[1] << 8 | ...
if (s[4] <= ' ') { op[i++] = s[0] | s[1] << 8 | ...
break;
}
op[i] = 0;
return i;
}
a_static void a_Token0Table_ini(a_Token0Table *w)
{
static uint32_t op4[64], op3[64], op2[64], op1[64];
a_Token0Table_iniSub(op4, "");
a_Token0Table_iniSub(op3, ">>= <<= ...");
a_Token0Table_iniSub(op2, "== != <= >= << >> ++ -- +...
a_Token0Table_iniSub(op1, "= < > + - * / % ^ & | ! ~...
int c;
for (c = 0; c < 256; c++) {
unsigned char ct = 0;
if (c != 0) {
if (strchr(" \t\r\n", c) != NULL) ct = 0;
if (strchr("(){},;[]\"\'", c) != NULL) ct = 1;
if (strchr("!#%&-=^~:+*<>./?|", c) != NULL) ...
if ('0' <= c && c <= '9') ct = 3;
if ('A' <= c && c <= 'Z') ct = 3;
if ('a' <= c && c <= 'z') ct = 3;
if (strchr("_$@`", c) != NULL) ct = 3;
}
w->chrTyp[c] = ct;
}
w->op[0] = op4;
w->op[1] = op3;
w->op[2] = op2;
w->op[3] = op1;
}
a_static char *a_Token0_get(a_Token0 *w)
{
const char *s = w->s, *s1 = w->s1;
unsigned char ct = 0, *chrTyp = w->tbl->chrTyp;
intptr_t len = 0, i; w->c = 0;
for (;;) {
if (s >= s1) goto fin;
ct = chrTyp[*(const unsigned char *) s];
if (ct == 0) { s++; continue; }
break;
}
if (ct == 1) {
len = 1;
w->c = *s;
goto fin;
}
if (ct == 2) {
unsigned char ch0 = *s, ch1 = 0, ch2 = 0, ch3 = 0;
if (s + 3 < s1) {
ch1 = s[1]; ch2 = s[2]; ch3 = s[3];
} else {
if (s + 1 < s1) ch1 = s[1];
if (s + 2 < s1) ch2 = s[2];
}
uint32_t op = ch0 | ch1 << 8 | ch2 << 16 | ch3 <...
opTbl = w->tbl->op[0]; len = 4; w->c = op;
for (i = 0; opTbl[i] != 0; i++) {
if (opTbl[i] == op) goto fin;
}
opTbl = w->tbl->op[1]; len = 3; w->c = op &= 0x0...
for (i = 0; opTbl[i] != 0; i++) {
if (opTbl[i] == op) goto fin;
}
opTbl = w->tbl->op[2]; len = 2; w->c = op &= 0x0...
for (i = 0; opTbl[i] != 0; i++) {
if (opTbl[i] == op) goto fin;
}
opTbl = w->tbl->op[3]; len = 1; w->c = op &= 0x0...
for (i = 0; opTbl[i] != 0; i++) {
if (opTbl[i] == op) goto fin;
}
ct = 255; len = 0; w->c = 0;
}
if (ct == 3) {
w->c = *s;
for (len = 1;;) {
if (s + len >= s1) goto fin;
if (chrTyp[((unsigned char *) s)[len]] == ct...
break;
}
}
fin:
w->cTyp = ct;
w->len = len;
w->s = s + len;
return (char *) s;
}
a_static char *a_Token1_get(a_Token0 *w)
{
for (;;) {
const char *s = a_Token0_get(w), *s1 = w->s1, *t;
uint32_t c = w->c;
if (s >= s1) return (char *) s;
if (c == ('/' | '/' << 8)) {
t = memchr(s, '\n', s1 - s);
if (t != NULL) { w->s = t; continue; }
w->s = s1; w->len = 0; return (char *) s1;
}
if (c == 0x22 || c == 0x27) {
// 改行もしくはエスケープされていないcがでる...
t = s + 1;
for (;;) {
if (t >= s1) break;
if (*t == (char) c) { t++; break; }
if (*t == '\n') break;
if (*t != '\\') { t++; continue; }
t++;
if (t >= s1) break;
if (*t == '\n') break;
t++;
}
w->len = t - s;
w->s = t;
return (char *) s;
}
if ('0' <= c && c <= '9') {
t = s + w->len;
for (;;) {
if (t >= s1) break;
c = *t;
if (c == '.') { t++; continue; }
if ('0' <= c && c <= '9') { t++; continu...
if ('A' <= c && c <= 'Z') { t++; continu...
if ('a' <= c && c <= 'z') { t++; continu...
if (c == '_') { t++; continue; }
if ((c == '+' || c == '-') && t[-1] == '...
break;
}
w->len = t - s;
w->s = t;
return (char *) s;
}
return (char *) s;
}
}
a_static void a_Token0_ini1(a_Token0 *w)
{
static a_Token0Table t0t[1];
a_Token0Table_ini(t0t);
w->tbl = t0t;
}
a_static void a_memcpy( void *t, const void *s, intptr_t...
a_static void a_memmove(void *t, const void *s, intptr_t...
#if (a_Version >= 1)
#define VecChr_stkAdd a_VecChr_stkAdd
#define VecChr_stkRmv a_VecChr_stkRmv
#define VecChr_stkTop a_VecChr_stkTop
#define parseArgs_Arg a_parseArgs_Arg
#define parseArgs a_parseArgs
#define VecChr_convEsc a_VecChr_convEsc
#define ptrAdd a_ptrAdd
#define ptrSub a_ptrSub
#endif
a_static void *a_VecChr_stkAdd(a_VecChr *w, intptr_t sz)...
a_static void *a_VecChr_stkRmv(a_VecChr *w, intptr_t sz)...
a_static void *a_VecChr_stkTop(a_VecChr *w, intptr_t sz)...
a_class(a_parseArgs_Arg) { const char *s; intptr_t n; };
a_static char *a_parseArgs(a_Token0 *t0, a_VecChr *v)
{
intptr_t nest = 0, len;
char flg = 0;
a_VecChr_N(v) = 0;
const char *s = NULL, *t;
a_parseArgs_Arg *paa;
for (;;) {
len = t0->len; t = s;
s = a_Token1_get(t0);
if (t0->len == 0) {
if (flg != 0) {
paa = a_VecChr_stkTop(v, sizeof (a_parse...
paa->n = t + len - paa->s;
}
break;
}
if (*s == ',') {
if (nest == 0 && flg != 0) {
paa = a_VecChr_stkTop(v, sizeof (a_parse...
paa->n = t + len - paa->s; flg = 0;
}
continue;
}
if (*s == ')' || *s == '}' || *s == ']') nest--;
if (nest < 0) {
if (flg != 0) {
paa = a_VecChr_stkTop(v, sizeof (a_parse...
paa->n = t + len - paa->s;
}
break;
}
if (flg == 0 && nest == 0) {
paa = a_VecChr_stkAdd(v, sizeof (a_parseArgs...
paa->s = s; flg = 1;
}
if (*s == '(' || *s == '{' || *s == '[') nest++;
}
return (char *) s;
}
a_static void a_VecChr_convEsc(a_VecChr *w)
{
a_VecChr_reserveDiff(w, 4);
memset(w->p + ((intptr_t *) w->p)[-1], 0, 4);
char *p, *q, *p1;
p = q = w->p;
p1 = p + ((intptr_t *) w->p)[-1];
while (p < p1) {
if (*p == '\\') {
if (p[1] == 'a') { *q++ = '\a'; p += 2; cont...
if (p[1] == 'b') { *q++ = '\b'; p += 2; cont...
if (p[1] == 'f') { *q++ = '\f'; p += 2; cont...
if (p[1] == 'n') { *q++ = '\n'; p += 2; cont...
if (p[1] == 'r') { *q++ = '\r'; p += 2; cont...
if (p[1] == 't') { *q++ = '\t'; p += 2; cont...
if (p[1] == 'v') { *q++ = '\v'; p += 2; cont...
if (p[1] == 'x') {
*q++ = (char) strtol(p + 1, &p, 16);
if (strchr(",.;:", *p) != NULL) p++;
continue;
}
if ('0' <= p[1] && p[1] <= '7') {
*q++ = (char) strtol(p + 1, &p, 8);
if (strchr(",.;:", *p) != NULL) p++;
continue;
}
p++;
*q++ = *p++;
} else
*q++ = *p++;
}
((intptr_t *) w->p)[-1] -= p1 - q;
a_VecChr_reserve0(w);
}
a_static void *a_ptrAdd(void *p, intptr_t i)
{
if (p != NULL) p = ((char *) p) + i;
return p;
}
a_static void *a_ptrSub(void *p, intptr_t i)
{
if (p != NULL) p = ((char *) p) - i;
return p;
}
** (99) 更新履歴
-2026.04.23(木) 初版
-2026.05.06(水) a_Token0Table_ini()のバグを修正
終了行:
* acl4のページ0018
-(by [[K]], 2026.04.23)
** (1) 概要
-a4_0018 は、 acl4v1 にとっての3番目のライブラリプログラ...
-提供される主な機能は、以下の通りです。
--(1-1)ファイルなどの文字列からトークンを切り出す Token0/...
--(1-2)VecChrを使ってスタック構造を作って読み書きする Vec...
--(1-3)かっこでくくられた構造を切り分ける parseArgs
--(1-4)Cの文字列リテラルで使われるエスケープシーケンスを...
-以下、それぞれについてもう少し詳しく説明します。
~
-(1-1)ファイルなどの文字列からトークンを切り出す Token0/T...
--プログラミング言語を作るなら、トークン繰り出し関数があ...
-(1-2)VecChrを使ってスタック構造を作って読み書きする VecC...
--Add が push で、Rmv が pop(pull) です。 x86 などのスタ...
-(1-3)かっこでくくられた構造を切り分ける parseArgs
--「(a,b+c,d-3)」みたいな文字列を、「a」「b+c」「d-3」に...
-(1-4)の文字列リテラルで使われるエスケープシーケンスをデ...
--\nとか\tなどをしかるべき文字コードに置換していきます。
** (2) デモ
** (3) ライブラリプログラム
#if (a_Version >= 1)
#define Token0 a_Token0
#define Token0Table a_Token0Table
#define Token0Table_ini a_Token0Table_ini
#define Token0_get a_Token0_get
#define Token1_get a_Token1_get
#define Token0_ini1 a_Token0_ini1
#endif
a_class(a_Token0Table) {
uint32_t *op[4];
unsigned char chrTyp[256];
// 0: 空白類.
// 1: 1文字記号.
// 2: 一般記号文字.
// 3: アルファベット/数字.
};
a_class(a_Token0) {
a_Token0Table *tbl;
const char *s, *s1;
unsigned char cTyp;
uint32_t c;
intptr_t len;
};
a_static int a_Token0Table_iniSub(uint32_t *op, const ch...
{
int i = 0;
for (;;) {
while (*s == ' ') s++;
if (*s == '\0') break;
if (s[1] <= ' ') { op[i++] = s[0]; ...
if (s[2] <= ' ') { op[i++] = s[0] | s[1] << 8; ...
if (s[3] <= ' ') { op[i++] = s[0] | s[1] << 8 | ...
if (s[4] <= ' ') { op[i++] = s[0] | s[1] << 8 | ...
break;
}
op[i] = 0;
return i;
}
a_static void a_Token0Table_ini(a_Token0Table *w)
{
static uint32_t op4[64], op3[64], op2[64], op1[64];
a_Token0Table_iniSub(op4, "");
a_Token0Table_iniSub(op3, ">>= <<= ...");
a_Token0Table_iniSub(op2, "== != <= >= << >> ++ -- +...
a_Token0Table_iniSub(op1, "= < > + - * / % ^ & | ! ~...
int c;
for (c = 0; c < 256; c++) {
unsigned char ct = 0;
if (c != 0) {
if (strchr(" \t\r\n", c) != NULL) ct = 0;
if (strchr("(){},;[]\"\'", c) != NULL) ct = 1;
if (strchr("!#%&-=^~:+*<>./?|", c) != NULL) ...
if ('0' <= c && c <= '9') ct = 3;
if ('A' <= c && c <= 'Z') ct = 3;
if ('a' <= c && c <= 'z') ct = 3;
if (strchr("_$@`", c) != NULL) ct = 3;
}
w->chrTyp[c] = ct;
}
w->op[0] = op4;
w->op[1] = op3;
w->op[2] = op2;
w->op[3] = op1;
}
a_static char *a_Token0_get(a_Token0 *w)
{
const char *s = w->s, *s1 = w->s1;
unsigned char ct = 0, *chrTyp = w->tbl->chrTyp;
intptr_t len = 0, i; w->c = 0;
for (;;) {
if (s >= s1) goto fin;
ct = chrTyp[*(const unsigned char *) s];
if (ct == 0) { s++; continue; }
break;
}
if (ct == 1) {
len = 1;
w->c = *s;
goto fin;
}
if (ct == 2) {
unsigned char ch0 = *s, ch1 = 0, ch2 = 0, ch3 = 0;
if (s + 3 < s1) {
ch1 = s[1]; ch2 = s[2]; ch3 = s[3];
} else {
if (s + 1 < s1) ch1 = s[1];
if (s + 2 < s1) ch2 = s[2];
}
uint32_t op = ch0 | ch1 << 8 | ch2 << 16 | ch3 <...
opTbl = w->tbl->op[0]; len = 4; w->c = op;
for (i = 0; opTbl[i] != 0; i++) {
if (opTbl[i] == op) goto fin;
}
opTbl = w->tbl->op[1]; len = 3; w->c = op &= 0x0...
for (i = 0; opTbl[i] != 0; i++) {
if (opTbl[i] == op) goto fin;
}
opTbl = w->tbl->op[2]; len = 2; w->c = op &= 0x0...
for (i = 0; opTbl[i] != 0; i++) {
if (opTbl[i] == op) goto fin;
}
opTbl = w->tbl->op[3]; len = 1; w->c = op &= 0x0...
for (i = 0; opTbl[i] != 0; i++) {
if (opTbl[i] == op) goto fin;
}
ct = 255; len = 0; w->c = 0;
}
if (ct == 3) {
w->c = *s;
for (len = 1;;) {
if (s + len >= s1) goto fin;
if (chrTyp[((unsigned char *) s)[len]] == ct...
break;
}
}
fin:
w->cTyp = ct;
w->len = len;
w->s = s + len;
return (char *) s;
}
a_static char *a_Token1_get(a_Token0 *w)
{
for (;;) {
const char *s = a_Token0_get(w), *s1 = w->s1, *t;
uint32_t c = w->c;
if (s >= s1) return (char *) s;
if (c == ('/' | '/' << 8)) {
t = memchr(s, '\n', s1 - s);
if (t != NULL) { w->s = t; continue; }
w->s = s1; w->len = 0; return (char *) s1;
}
if (c == 0x22 || c == 0x27) {
// 改行もしくはエスケープされていないcがでる...
t = s + 1;
for (;;) {
if (t >= s1) break;
if (*t == (char) c) { t++; break; }
if (*t == '\n') break;
if (*t != '\\') { t++; continue; }
t++;
if (t >= s1) break;
if (*t == '\n') break;
t++;
}
w->len = t - s;
w->s = t;
return (char *) s;
}
if ('0' <= c && c <= '9') {
t = s + w->len;
for (;;) {
if (t >= s1) break;
c = *t;
if (c == '.') { t++; continue; }
if ('0' <= c && c <= '9') { t++; continu...
if ('A' <= c && c <= 'Z') { t++; continu...
if ('a' <= c && c <= 'z') { t++; continu...
if (c == '_') { t++; continue; }
if ((c == '+' || c == '-') && t[-1] == '...
break;
}
w->len = t - s;
w->s = t;
return (char *) s;
}
return (char *) s;
}
}
a_static void a_Token0_ini1(a_Token0 *w)
{
static a_Token0Table t0t[1];
a_Token0Table_ini(t0t);
w->tbl = t0t;
}
a_static void a_memcpy( void *t, const void *s, intptr_t...
a_static void a_memmove(void *t, const void *s, intptr_t...
#if (a_Version >= 1)
#define VecChr_stkAdd a_VecChr_stkAdd
#define VecChr_stkRmv a_VecChr_stkRmv
#define VecChr_stkTop a_VecChr_stkTop
#define parseArgs_Arg a_parseArgs_Arg
#define parseArgs a_parseArgs
#define VecChr_convEsc a_VecChr_convEsc
#define ptrAdd a_ptrAdd
#define ptrSub a_ptrSub
#endif
a_static void *a_VecChr_stkAdd(a_VecChr *w, intptr_t sz)...
a_static void *a_VecChr_stkRmv(a_VecChr *w, intptr_t sz)...
a_static void *a_VecChr_stkTop(a_VecChr *w, intptr_t sz)...
a_class(a_parseArgs_Arg) { const char *s; intptr_t n; };
a_static char *a_parseArgs(a_Token0 *t0, a_VecChr *v)
{
intptr_t nest = 0, len;
char flg = 0;
a_VecChr_N(v) = 0;
const char *s = NULL, *t;
a_parseArgs_Arg *paa;
for (;;) {
len = t0->len; t = s;
s = a_Token1_get(t0);
if (t0->len == 0) {
if (flg != 0) {
paa = a_VecChr_stkTop(v, sizeof (a_parse...
paa->n = t + len - paa->s;
}
break;
}
if (*s == ',') {
if (nest == 0 && flg != 0) {
paa = a_VecChr_stkTop(v, sizeof (a_parse...
paa->n = t + len - paa->s; flg = 0;
}
continue;
}
if (*s == ')' || *s == '}' || *s == ']') nest--;
if (nest < 0) {
if (flg != 0) {
paa = a_VecChr_stkTop(v, sizeof (a_parse...
paa->n = t + len - paa->s;
}
break;
}
if (flg == 0 && nest == 0) {
paa = a_VecChr_stkAdd(v, sizeof (a_parseArgs...
paa->s = s; flg = 1;
}
if (*s == '(' || *s == '{' || *s == '[') nest++;
}
return (char *) s;
}
a_static void a_VecChr_convEsc(a_VecChr *w)
{
a_VecChr_reserveDiff(w, 4);
memset(w->p + ((intptr_t *) w->p)[-1], 0, 4);
char *p, *q, *p1;
p = q = w->p;
p1 = p + ((intptr_t *) w->p)[-1];
while (p < p1) {
if (*p == '\\') {
if (p[1] == 'a') { *q++ = '\a'; p += 2; cont...
if (p[1] == 'b') { *q++ = '\b'; p += 2; cont...
if (p[1] == 'f') { *q++ = '\f'; p += 2; cont...
if (p[1] == 'n') { *q++ = '\n'; p += 2; cont...
if (p[1] == 'r') { *q++ = '\r'; p += 2; cont...
if (p[1] == 't') { *q++ = '\t'; p += 2; cont...
if (p[1] == 'v') { *q++ = '\v'; p += 2; cont...
if (p[1] == 'x') {
*q++ = (char) strtol(p + 1, &p, 16);
if (strchr(",.;:", *p) != NULL) p++;
continue;
}
if ('0' <= p[1] && p[1] <= '7') {
*q++ = (char) strtol(p + 1, &p, 8);
if (strchr(",.;:", *p) != NULL) p++;
continue;
}
p++;
*q++ = *p++;
} else
*q++ = *p++;
}
((intptr_t *) w->p)[-1] -= p1 - q;
a_VecChr_reserve0(w);
}
a_static void *a_ptrAdd(void *p, intptr_t i)
{
if (p != NULL) p = ((char *) p) + i;
return p;
}
a_static void *a_ptrSub(void *p, intptr_t i)
{
if (p != NULL) p = ((char *) p) - i;
return p;
}
** (99) 更新履歴
-2026.04.23(木) 初版
-2026.05.06(水) a_Token0Table_ini()のバグを修正
ページ名: