static int parse (char delim, bool skipPrefix =false) { int ch = nextCh(); if (ch >= 0) { bool stop = ch == 0 || padFill >= PAD_SIZE; if (stop || ch == delim || (delim == ' ' && ch <= delim)) { if (skipPrefix && padFill == 0 && !stop) return -1; padDelim = ch; pad[padFill] = 0; int len = padFill; padFill = 0; return len; } pad[padFill++] = ch; } return -1; }
Token nextTkn(void) /* 次のトークン */ { Token tkn = {NulKind, "", 0}; int errF = FALSE, num, ct, n; char *p = tkn.text, *p_end31 = p+ID_SIZ; char lite[100+1], *lite_end = lite+100; static int ch = ' '; /* 前回文字を保持するためstatic */ while (isspace(ch)) { ch = nextCh(); } /* 空白読み捨て */ if (ch == EOF) { tkn.kind = EofTkn; return tkn; } /* EOF */ switch (ctyp[ch]) { case Letter: for ( ; ctyp[ch]==Letter || ctyp[ch]==Digit; ch = nextCh()) { if (p < p_end31) *p++ = ch; /* 識別子は最大31文字まで有効 */ } *p = '\0'; break; case Digit: /* 数値定数 */ for (num=0; ctyp[ch]==Digit; ch = nextCh()) { num = num*10 + (ch-'0'); } tkn.kind = IntNum; tkn.intVal = num; /* 値格納 */ sprintf(tkn.text, "%d", num); /* エラー表示用 */ break; case SngQ: /* 文字定数 */ for (ct=0,ch=nextCh(); ch!=EOF && ch!='\n' && ch!='\''; ch=nextCh()) { if (ch == '\\') { if ((ch=nextCh()) == 'n') ch = '\n'; } /* \nの処理 */ if (++ct == 1) tkn.intVal = ch; /* 文字定数値格納 */ } if (ct != 1) errF = TRUE; if (ch == '\'') ch = nextCh(); else errF = TRUE; if (errF) err_s("不正な文字定数"); tkn.kind = IntNum; /* 以降は整数定数として扱う */ sprintf(tkn.text, "'%c'", tkn.intVal); /* エラー表示用 */ break; case DblQ: /* 文字列定数 */ p = lite; ch = nextCh(); while (ch!=EOF && ch!='\n' && ch!='"') { if (errF) { ch = nextCh(); continue; } if ((n=is_kanji(ch)) > 0) { while (n--) { if (p < lite_end) P_SET(); else errF = TRUE; } continue; } if (ch == '\\') { if ((ch=nextCh()) == 'n') ch = '\n'; } /* \nの処理 */ if (p < lite_end) P_SET(); else errF = TRUE; } *p = '\0'; if (errF) err_s("文字列リテラルが長すぎる"); if (ch == '"') ch = nextCh(); else err_s("文字列リテラルが閉じていない"); tkn.kind = String; tkn.intVal = mallocS(lite); /* 文字列をメモリに確保し番地を格納 */ tkn.text[0] = '\"'; /*以下エラー表示用に文字列確保*/ strncat(tkn.text+1, lite, 29); if (strlen(tkn.text) <= 29) strcat(tkn.text, "\""); break; default: /* 記号 */ if (ch<0 || 127<ch) err_s("不正な文字が使われている"); if ((n=is_kanji(ch)) > 0) { while (n--) P_SET(); } else P_SET(); if (is_ope2(*(p-1), ch)) P_SET(); /* == など */ *p = '\0'; } if (tkn.kind == NulKind) tkn = set_kind(tkn); /* 種別設定 */ if (tkn.kind == Others) err_ss("不正なトークン", tkn.text); return tkn; }
void AsmBuf::relational(Value *val) { Value v2; bool fLabel; orExpr(&v2); fLabel = v2.fLabel; while(1) { switch(nextNonSpaceLF()) { case '<': if (peekCh() == '>') { nextCh(); orExpr(val); v2.value = v2.value != val->value; v2.size = getSizeCh(v2.size, val->size); fLabel = false; } else if (peekCh() == '=') { nextCh(); orExpr(val); v2.value = v2.value <= val->value; v2.size = getSizeCh(v2.size, val->size); fLabel = false; } else if (peekCh() != '<') { orExpr(val); v2.value = v2.value < val->value; v2.size = getSizeCh(v2.size, val->size); fLabel = false; } else { unNextCh(); goto xitLoop; } break; case '>': if (peekCh() == '=') { nextCh(); orExpr(val); v2.value = v2.value >= val->value; v2.size = getSizeCh(v2.size, val->size); fLabel = false; } else if (peekCh() != '>') { orExpr(val); v2.value = v2.value > val->value; v2.size = getSizeCh(v2.size, val->size); fLabel = false; } else { unNextCh(); goto xitLoop; } break; case '=': orExpr(val); v2.value = v2.value == val->value; v2.size = getSizeCh(v2.size, val->size); fLabel = false; break; case '!': if (peekCh() == '=') { nextCh(); orExpr(val); v2.value = v2.value != val->value; v2.size = getSizeCh(v2.size, val->size); fLabel = false; } else { unNextCh(); goto xitLoop; } break; default: unNextCh(); goto xitLoop; } } xitLoop: *val = v2; val->fLabel = fLabel; return; }
String *AsmBuf::getArg() { int Depth = 0; char c; int dqcount = 0, sqcount = 0; String *arg = new String(); skipSpacesLF(); while(1) { c = (char)peekCh(); // Quit loop on newline or end of buffer. if (c < 1 || c == '\n') break; switch (c) { // If quote encountered then scan till closing quote or end of line case '"': arg->add(c); nextCh(); while(1) { c = (char)nextCh(); if (c < 1 || c == '\n') goto EndOfLoop; arg->add(c); if (c == '"') break; } continue; // If quote encountered then scan till closing quote or end of line case '\'': arg->add(c); nextCh(); while(1) { c = (char)nextCh(); if (c < 1 || c == '\n') goto EndOfLoop; arg->add(c); if (c == '\'') break; } continue; case '(': Depth++; break; case ')': if (Depth < 1) // check if we hit the end of the arg Err(E_CPAREN); Depth--; break; case ',': if (Depth == 0) // comma at outermost level means goto EndOfLoop; // end of argument has been found break; // On semicolon scan to end of line without copying characters to arg case ';': goto EndOfLoop; // while(1) { // c = (char)nextCh(); // if (c < 1 || c == '\n') // goto EndOfLoop; // } } arg->add(c); // copy input argument to argstr. nextCh(); } EndOfLoop: if (Depth > 0) Err(E_PAREN); //printf("arg:%s|", arg->buf()); arg->trim(); // get rid of spaces around argument return arg; }