YACASL2
Loading...
Searching...
No Matches
token.c
Go to the documentation of this file.
1#include "token.h"
2
10OPD *opdtok(const char *str);
11
16 { 104, "label length is too long" },
17 { 105, "no command in the line" },
18};
19
23static CERR cerr_opdtok[] = {
24 { 117, "operand too many in DC" },
25 { 118, "operand length too long" },
26 { 121, "cannot get operand token" },
27 { 123, "unclosed quote" },
28};
29
30OPD *opdtok(const char *str)
31{
32 OPD *opd = malloc_chk(sizeof(OPD), "opd");
33 char *tok, *p, sepc = ',';
34 int i = 0, cnt_quote = 0;
35 bool quoting = false;
36
37 opd->opdc = 0;
38 if(!str || !str[0]) {
39 return opd;
40 }
41 tok = p = strdup_chk(str, "opdtok.p");
42 do {
43 /* オペランド数が多すぎる場合はエラー */
44 if(opd->opdc >= OPDSIZE) {
45 setcerr(117, ""); /* operand is too many */
46 break;
47 }
48 /* 先頭が等号(=)の場合 */
49 if(p[i] == '=') {
50 i++;
51 }
52 /* 「'」の場合 */
53 if(p[i] == '\'') {
54 /* 「''」以外の場合はquote値を反転する */
55 if(p[i+1] != '\'' && (quoting == false || p[i-1] != '\'')) {
56 quoting = !quoting;
57 }
58 /* 「'」をカウントする。「''」の場合は1をカウント */
59 if(p[i+1] != '\'') {
60 cnt_quote++;
61 }
62 }
63 if(quoting == true) {
64 /* 「'」で開いたまま文字列が終了した場合 */
65 if(!p[i]) {
66 setcerr(123, str); /* unclosed quote */
67 break;
68 }
69 i++;
70 } else {
71 i += strcspn(p + i, ", ");
72 if(i == 0) {
73 setcerr(121, ""); /* cannot get operand token */
74 break;
75 }
76 if(i - cnt_quote > OPDSIZE) {
77 setcerr(118, ""); /* operand length too long */
78 break;
79 }
80 sepc = p[i];
81 opd->opdv[(opd->opdc)++] = strndup_chk(p, i, "opd->opdv[]");
82 p += i + 1;
83 i = cnt_quote = 0;
84 }
85 } while(sepc == ',');
86 FREE(tok);
87 return opd;
88}
89
90/* assemble.hで定義された関数群 */
96
97CMDLINE *linetok(const char *line)
98{
99 char *tok = NULL, *p = NULL;
100 int i;
101 CMDLINE *cmdl = NULL;
102
103 assert(line);
104 if(!line[0] || line[0] == '\n') {
105 return NULL;
106 }
107 tok = p = strdup_chk(line, "tok");
108 /* コメントを削除 */
110 /* 文字列末尾の改行と空白を削除 */
111 strip_end(p);
112 /* 空行の場合、終了 */
113 if(!p[0]) {
114 goto linetokfin;
115 }
116 cmdl = malloc_chk(sizeof(CMDLINE), "cmdl");
117
118 /* ラベルの取得 */
119 /* 行の先頭が空白またはタブの場合、ラベルは空 */
120 if((i = strcspn(p, " \t")) == 0) {
121 cmdl->label = strdup_chk("", "cmdl->label");
122 } else {
123 cmdl->label = strndup_chk(p, i, "cmdl->label");
124 /* ラベルの文字列が長すぎる場合はエラー */
125 if(i > LABELSIZE) {
126 setcerr(104, cmdl->label); /* label length is too long */
127 FREE(cmdl->label);
128 goto linetokfin;
129 }
130 }
131
132 /* 命令の取得 */
133 /* 文字列先頭をラベルの次の文字に移動 */
134 p += i;
135 /* 文字列先頭を、ラベルと命令の間の空白の後ろに移動 */
136 p += strspn(p, " \t");
137 /* 命令がない場合は、終了 */
138 if(!p[0]) {
139 if(cmdl->label) { /* ラベルが定義されていて命令がない場合はエラー */
140 setcerr(105, ""); /* no command in the line */
141 }
142 FREE(cmdl->label);
143 FREE(cmdl);
144 goto linetokfin;
145 }
146 /* 命令取得の実行 */
147 i = strcspn(p, " \t");
148 cmdl->cmd = strndup_chk(p, i, "cmdl.cmd");
149
150 /* オペランドの取得 */
151 /* 文字列先頭を、命令の次の文字に移動 */
152 p += i;
153 /* 文字列先頭を、命令とオペランドの間の空白の後ろに移動 */
154 p += strspn(p, " \t");
155 /* オペランド取得の実行 */
156 cmdl->opd = opdtok(p);
157linetokfin:
158 FREE(tok);
159 return cmdl;
160}
struct _CERR CERR
エラーを表すデータ型
void addcerrlist(int cerrc, CERR cerrv[])
エラーリストを作成・追加する
Definition cerr.c:13
void setcerr(int num, const char *str)
現在のエラーを設定する
Definition cerr.c:45
#define FREE(ptr)
メモリを解放するマクロ
Definition cmem.h:21
void strip_end(char *s)
文字列の末尾から、改行と空白とタブを削除する
Definition cmem.c:48
char * strndup_chk(const char *s, size_t len, const char *tag)
malloc_chkを実行してメモリを確保し、コピーした文字列の指定した長さの部分を返す
Definition cmem.c:33
void strip_casl2_comment(char *s)
文字列から「'」以降の文字列をCASL IIのコメントとして削除する。「''」の場合は除く
Definition cmem.c:55
void * malloc_chk(size_t size, const char *tag)
mallocを実行し、0で初期化する
Definition cmem.c:3
#define ARRAYSIZE(array)
配列のサイズを返すマクロ
Definition cmem.h:14
char * strdup_chk(const char *s, const char *tag)
malloc_chkを実行してメモリを確保し、コピーした文字列を返す
Definition cmem.c:25
命令行を表すデータ型
Definition token.h:41
OPD * opd
Definition token.h:44
char * cmd
Definition token.h:43
char * label
Definition token.h:42
オペランドを表すデータ型
Definition token.h:33
int opdc
Definition token.h:34
char * opdv[OPDSIZE]
Definition token.h:35
CMDLINE * linetok(const char *line)
行から、ラベル・コマンド・オペランドを取得する
Definition token.c:97
void addcerrlist_tok()
トークン取得のエラーを追加する
Definition token.c:91
static CERR cerr_opdtok[]
オペランドトークン取得のエラー定義
Definition token.c:23
OPD * opdtok(const char *str)
「,」区切りの文字列から、オペランドのトークンを取得
Definition token.c:30
CERR cerr_linetok[]
行トークン取得のエラー定義
Definition token.c:15
@ LABELSIZE
Definition token.h:18
@ OPDSIZE
Definition token.h:19