0Pricing
C Academy · 강의

입력 토큰화하기

텍스트를 토큰으로 변환해 보세요.

입력 토큰화하기은(는) CoddyKit의 무료 C Academy 강의입니다. 이것은 4개 중 1번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 C Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. C Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

토크나이저란 무엇인가요

인터프리터는 먼저 원시 텍스트를 토큰으로 바꿉니다. 토큰은 의미를 가진 가장 작은 단위입니다. 3 + 4 * 2라는 문자열의 경우 토크나이저 또는 어휘 분석기가 숫자와 연산자를 출력합니다.

이 단계에서는 공백을 제거하고 각 문자 묶음을 분류하므로 파서는 원시 바이트를 직접 다루지 않습니다.

토큰 형식

각 토큰을 열거형 태그와 payload로 표현합니다. 숫자에는 정수 값이 들어가고, 연산자와 괄호에는 종류만 있으면 됩니다.

값을 구조체 안에 보관하면 나중에 원본을 다시 스캔하지 않아도 됩니다.

typedef enum {
  TOK_NUM, TOK_PLUS, TOK_MINUS,
  TOK_STAR, TOK_SLASH,
  TOK_LPAREN, TOK_RPAREN, TOK_EOF
} TokKind;

typedef struct {
  TokKind kind;
  int value; /* used when kind == TOK_NUM */
} Token;

스캔 위치

어휘 분석기는 커서 포인터로 원본을 순회합니다. 작은 도우미 함수가 현재 문자를 소비하지 않고 미리 확인하며, 끝에 도달하면 '\0'을 반환합니다.

포인터 연산을 사용하면 스캐너를 빠르고 단순하게 유지할 수 있습니다.

static const char *src;

static char peek(void) {
  return *src;
}

static char advance(void) {
  return *src++;
}

공백 건너뛰기

토큰을 읽기 전에 공백과 탭을 버립니다. <ctype.h>의 표준 isspace가 모든 공백 문자를 처리합니다.

여기서는 줄 바꿈도 공백으로 취급하므로 표현식이 여러 줄에 걸쳐 있을 수 있습니다.

#include <ctype.h>

static void skip_ws(void) {
  while (isspace((unsigned char)peek()))
    advance();
}

숫자 어휘 분석

커서가 숫자에 놓이면 연속된 숫자를 정수로 누적합니다. 10을 곱한 뒤 각 숫자를 더하면 왼쪽에서 오른쪽으로 값이 만들어집니다.

반복은 첫 번째 숫자가 아닌 문자에서 멈추며, 커서는 다음 토큰을 읽을 준비가 됩니다.

static int lex_number(void) {
  int n = 0;
  while (isdigit((unsigned char)peek())) {
    n = n * 10 + (advance() - '0');
  }
  return n;
}

next_token 함수

핵심 루틴은 공백을 건너뛴 다음 현재 문자에 따라 작업을 나눕니다. 숫자는 TOK_NUM이 되고 각 연산자는 고유한 종류로 매핑됩니다.

종료 NUL에 도달하면 중지 신호인 TOK_EOF가 생성됩니다.

static Token next_token(void) {
  skip_ws();
  char c = peek();
  if (c == '\0') return (Token){TOK_EOF, 0};
  if (isdigit((unsigned char)c))
    return (Token){TOK_NUM, lex_number()};
  advance();
  switch (c) {
    case '+': return (Token){TOK_PLUS, 0};
    case '-': return (Token){TOK_MINUS, 0};
    case '*': return (Token){TOK_STAR, 0};
    case '/': return (Token){TOK_SLASH, 0};
    case '(': return (Token){TOK_LPAREN, 0};
    case ')': return (Token){TOK_RPAREN, 0};
  }
  return (Token){TOK_EOF, 0};
}

어휘 분석기 실행하기

여기에는 표현식을 토큰화하고 각 토큰 종류를 출력하는 완전한 프로그램이 있습니다. 숫자의 값도 함께 출력합니다.

TOK_EOF를 읽으면 반복이 끝나는 점에 주목하세요.

#include <stdio.h>
#include <ctype.h>

typedef enum { TOK_NUM, TOK_PLUS, TOK_STAR, TOK_EOF } TokKind;
typedef struct { TokKind kind; int value; } Token;

static const char *src;
static char peek(void){ return *src; }
static char advance(void){ return *src++; }

static Token next_token(void){
  while (isspace((unsigned char)peek())) advance();
  char c = peek();
  if (c=='\0') return (Token){TOK_EOF,0};
  if (isdigit((unsigned char)c)){
    int n=0; while(isdigit((unsigned char)peek())) n=n*10+(advance()-'0');
    return (Token){TOK_NUM,n};
  }
  advance();
  if (c=='+') return (Token){TOK_PLUS,0};
  return (Token){TOK_STAR,0};
}

int main(void){
  src = "12 + 3 * 4";
  Token t;
  do {
    t = next_token();
    if (t.kind==TOK_NUM) printf("NUM %d\n", t.value);
    else if (t.kind==TOK_PLUS) printf("PLUS\n");
    else if (t.kind==TOK_STAR) printf("STAR\n");
    else printf("EOF\n");
  } while (t.kind != TOK_EOF);
  return 0;
}

토큰 하나 미리 보기

파서는 보통 다음 토큰을 소비하기 전에 검사해야 합니다. 전역 current에 토큰 하나를 저장하고 일치시킬 때마다 다시 채웁니다.

이 하나의 토큰 미리 보기만으로도 LL(1) 문법에는 충분합니다.

static Token current;

static void init_lexer(const char *s) {
  src = s;
  current = next_token();
}

static Token cur(void) { return current; }

static void bump(void) { current = next_token(); }

어휘 오류 보고하기

$나 @ 같은 알 수 없는 문자를 조용히 사라지게 해서는 안 됩니다. 견고한 어휘 분석기는 문제가 된 바이트를 보고하고 중단합니다.

어휘 분석기에서 즉시 실패하면 이후 단계가 잘못된 토큰을 보지 않게 됩니다.

#include <stdio.h>
#include <stdlib.h>

static void lex_error(char c) {
  fprintf(stderr, "lex error: unexpected '%c'\n", c);
  exit(1);
}

여러 문자로 이루어진 연산자

실제 언어에는 ==나 <= 같은 토큰이 있습니다. 이를 어휘 분석하려면 첫 문자 뒤의 문자 하나를 더 미리 확인합니다.

다음 바이트가 연산자를 완성하면 두 문자를 모두 소비하고, 그렇지 않으면 한 문자 형식을 출력합니다.

/* fragment: distinguish '=' from '==' */
if (peek() == '=') {
  advance();
  if (peek() == '=') { advance(); /* TOK_EQ */ }
  else { /* TOK_ASSIGN */ }
}

토큰이 중요한 이유

문자를 토큰으로 합치면 파서는 정리되고 형식이 지정된 스트림을 다룰 수 있습니다. 연산자 우선순위, 그룹화, 오류를 모두 더 쉽게 이해하고 처리할 수 있습니다.

다음에는 이 토큰을 재귀 하강 파서에 입력합니다.

빠른 확인

어휘 분석기가 그룹화 기호에 대해 무엇을 출력하는지 생각해 보세요.

복습

토큰 형식, 스캔 커서, 공백 건너뛰기, 숫자 어휘 분석, 그리고 한 토큰 미리 보기를 지원하는 next_token 분배기를 갖춘 어휘 분석기를 만들었습니다.

이 토큰은 구문 분석의 입력이며, 구문 분석은 토큰으로부터 구문 트리를 만듭니다.

자주 묻는 질문

“입력 토큰화하기” 강의는 무료인가요?

네 — “입력 토큰화하기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 C Academy 강의 전체를 잠금 해제할 수 있습니다. C Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“입력 토큰화하기”에서 뭘 배우나요?

텍스트를 토큰으로 변환해 보세요. 브라우저에서 직접 실행하는 실습 코드로 C Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

C Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 C Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 1번째 강의입니다.

“입력 토큰화하기” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 C Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 C Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 입력 토큰화하기
  2. 식 구문 분석하기
  3. 트리 평가하기
  4. 변수 추가하기
← C Academy(으)로 돌아가기