Пример #1
0
Token nextTkn() /* 다음 토큰 */
{
  TknKind kd;
  string txt = "";

  if (endOfFile_F) return Token(EofProg);                     /* 파일 종료 */
  while (isspace(CH)) NEXT_CH();                              /* 공백 스킵 */
  if (CH == '\0')  return Token(EofLine);                          /* 행끝 */

  switch (ctyp[CH]) {
  case Doll: case Letter:
    txt += CH; NEXT_CH();
    while (ctyp[CH]==Letter || ctyp[CH]==Digit) { txt += CH; NEXT_CH(); }
    break;
  case Digit:                                                     /* 수치상수 */
    kd = IntNum;
    while (ctyp[CH] == Digit)   { txt += CH; NEXT_CH(); }
    if (CH == '.') { kd = DblNum; txt += CH; NEXT_CH(); }
    while (ctyp[CH] == Digit)   { txt += CH; NEXT_CH(); }
    return Token(kd, txt, atof(txt.c_str()));       /* IntNum도 double형으로 저장 */
  case DblQ:                                                    /* 문자열 상수 */
    NEXT_CH();
    while (CH!='\0' && CH!='"') { txt += CH; NEXT_CH(); }
    if (CH == '"') NEXT_CH(); else err_exit("문자열 리터럴이 닫혀있지 않다. ");
    return Token(String, txt);
  default:
    if (CH=='/' && C2=='/') return Token(EofLine);                /* 주석 */
    if (is_ope2(CH, C2)) { txt += CH; txt += C2; NEXT_CH(); NEXT_CH(); }
    else                 { txt += CH; NEXT_CH(); }
  }
  kd = get_kind(txt);                                             /* 종류별 설정 */

  if (kd == Others) err_exit("잘못된 토큰입니다: ", txt);
  return Token(kd, txt);
}
Пример #2
0
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;
}