Skip to content

isairz/cminus

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

27 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

C-Minus

Tiny Compiler ๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ C ๋ฌธ๋ฒ•์˜ Subset์ธ C-Minus๋ฅผ ์ง์ ‘ ์ œ์ž‘ํ•˜์—ฌ ๋ณธ๋‹ค.

Tested Environment

  • OS X Yosemite (10.10.3)
  • Ubuntu 14.04 LTS

Requirment

  • GCC
  • FLEX
  • BISON

Project 1 - Scanner

Overview

์Šค์บ๋„ˆ ์ œ์ž‘์„ ์œ„ํ•ด ํ‚ค์›Œ๋“œ, ์‹ฌ๋ณผ์„ ์ •์˜ํ•˜๊ณ  DFA๋ฅผ ์ด์šฉํ•ด ์ฃผ์–ด์ง„ ์†Œ์ŠคํŒŒ์ผ์˜ ๋ฌธ์ž์—ด์„ ํ† ํฐ ๋‹จ์œ„๋กœ ๋ถ„์„(Lexical Analysis)ํ•œ๋‹ค.

How to use

$ make cminus
$ ./cminus test.cm
$ make cminus_flex
$ ./cminus_flex test.cm

Definition

Keywords (lower case only)

  • else
  • if
  • int
  • return
  • void
  • while

Symbols

  • +
  • -
  • *
  • /
  • <
  • <=
  • >
  • >=
  • ==
  • !=
  • =
  • ;
  • ,
  • (
  • )
  • [
  • ]
  • {
  • }
  • /* */

Tokens

  • ๐ผ๐ท = ๐‘™๐‘’๐‘ก๐‘ก๐‘’๐‘Ÿ ๐‘™๐‘’๐‘ก๐‘ก๐‘’๐‘Ÿ*
  • ๐‘๐‘ˆ๐‘€ = ๐‘‘๐‘–๐‘”๐‘–๐‘ก ๐‘‘๐‘–๐‘”๐‘–๐‘ก *
  • ๐‘™๐‘’๐‘ก๐‘ก๐‘’๐‘Ÿ = a | ... | z | A | ... | Z
  • ๐‘‘๐‘–๐‘”๐‘–๐‘ก = 0 | 1 | ... | 9

๊ณผ์ œ ์ˆ˜ํ–‰

๋จผ์ € ์Šค์บ๋„ˆ๋งŒ ์ œ์ž‘ํ•˜๊ธฐ ์œ„ํ•ด main.c ์˜ FLAG๋“ค์„ ์กฐ์ •ํ•œ๋‹ค.

int EchoSource = TRUE;
int TraceScan = TRUE;
int TraceParse = FALSE;
int TraceAnalyze = FALSE;
int TraceCode = FALSE;

ํ‚ค์›Œ๋“œ์™€ ์‹ฌ๋ณผ ๋“ฑ๋ก์„ ์œ„ํ•ด global.h ์˜ enum ๊ฐ’์„ ์ˆ˜์ •ํ•œ๋‹ค. ์ด ๋•Œ MAXRESERVED์˜ ๊ฐœ์ˆ˜๋ฅผ ํ‚ค์›Œ๋“œ ์ˆ˜์™€ ๋ฐ˜๋“œ์‹œ ๊ฐ™๊ฒŒ ํ•ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค. ํ‚ค์›Œ๋“œ์˜ ์ฒ˜์Œ๊ณผ ๋์— KEYWORD_START, KEYWORD_END ๋ผ๋Š” enum์„ ์ถ”๊ฐ€ํ•˜์—ฌ ๊ด€๋ฆฌ ํ•˜๋ฉด ์‹ค์ˆ˜๋ฅผ ๋ฐฉ์ง€ ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค. ์ปดํŒŒ์ผ ์˜ค๋ฅ˜ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•ด tiny ์—์„œ ์“ฐ๋˜ enum์„ ๋‚จ๊ฒจ๋‘๊ณ , fixme๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

/* MAXRESERVED = the number of reserved words */
#define MAXRESERVED 6

typedef enum
    /* book-keeping tokens */
   {ENDFILE,ERROR,
    /* reserved words */
    ELSE,IF,INT,RETURN,VOID,WHILE,
    /* multicharacter tokens */
    ID,NUM,
    /* special symbols */
    PLUS,MINUS,TIMES,OVER,LT,LTEQ,GT,GTEQ,EQ,NEQ,ASSIGN,SEMI,COMMA,
    LPAREN,RPAREN,LBRACK,RBRACK,LBRACE,RBRACE,

    /* OLD symbols for compile */
    /* FIXME: Remove this symbols */
    THEN,END,UNTIL,REPEAT,READ,WRITE,
   } TokenType;

๋ณธ๊ฒฉ์ ์ธ DFA๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด scan.c๋ฅผ ์ˆ˜์ •ํ•œ๋‹ค. tiny์—์„œ ๋ฐฉ์‹ ๊ทธ๋Œ€๋กœ ํ•˜๋‚˜์”ฉ ๋ฐ”๋€Œ๋˜, 2๊ธ€์ž ์งœ๋ฆฌ ์—ฐ์‚ฐ์ž๋“ค์„ ์กฐ์‹ฌ์Šค๋Ÿฝ๊ฒŒ ์ถ”๊ฐ€ํ•œ๋‹ค.

ํŠนํžˆ /* */ ๋ฅผ ์ถ”๊ฐ€ํ• ๋•Œ ์ฃผ์˜ํ•œ๋‹ค. ์ฒซ slash๊ฐ€ ๋‚˜์™”์„๋•Œ, *๊ฐ€ ๋‚˜์™”์„๋•Œ, 2๋ฒˆ์งธ *์ด ๋‚˜์™”์„๋•Œ์˜ state๋ฅผ ๊ฐ๊ฐ ๋‚˜๋ˆ  ์ฒ˜๋ฆฌํ•œ๋‹ค.

case INSLASH:
  if (c == '*')
  { state = INCOMMENT;
    save = FALSE;
  }
  else
  { state = DONE;
    ungetNextChar();
    currentToken = OVER;
  }
  break;
case INCOMMENT:
  save = FALSE;
  if (c == EOF)
  { state = DONE;
    currentToken = ENDFILE;
  }
  else if (c == '*') state = INCOMMENTSTAR;
  break;
case INCOMMENTSTAR:
  save = FALSE;
  if (c == EOF)
  { state = DONE;
    currentToken = ENDFILE;
  }
  else if (c == '/') state = START;
  else state = INCOMMENT;
  break;

Results

TINY COMPILATION: test.cm
   1: /* A Program to perform Euclid`s
   2:    Algorithm to computer gcd */
   3:
   4: int gcd (int u, int v)
	4: reserved word: int
	4: ID, name= gcd
	4: (
	4: reserved word: int
	4: ID, name= u
	4: ,
	4: reserved word: int
	4: ID, name= v
	4: )
   5: {
	5: {
   6:     if (v == 0) return u;
	6: reserved word: if
	6: (
	6: ID, name= v
	6: ==
	6: NUM, val= 0
	6: )
	6: reserved word: return
	6: ID, name= u
	6: ;
   7:     else return gcd(v,u-u/v*v);
	7: reserved word: else
	7: reserved word: return
	7: ID, name= gcd
	7: (
	7: ID, name= v
	7: ,
	7: ID, name= u
	7: -
	7: ID, name= u
	7: /
	7: ID, name= v
	7: *
	7: ID, name= v
	7: )
	7: ;
   8:     /* u-u/v*v == u mod v */
   9: }
	9: }
  10:
  11: void main(void)
	11: reserved word: void
	11: ID, name= main
	11: (
	11: reserved word: void
	11: )
  12: {
	12: {
  13:     int x; int y;
	13: reserved word: int
	13: ID, name= x
	13: ;
	13: reserved word: int
	13: ID, name= y
	13: ;
  14:     x = input(); y = input();
	14: ID, name= x
	14: =
	14: ID, name= input
	14: (
	14: )
	14: ;
	14: ID, name= y
	14: =
	14: ID, name= input
	14: (
	14: )
	14: ;
  15:     output(gcd(x,y));
	15: ID, name= output
	15: (
	15: ID, name= gcd
	15: (
	15: ID, name= x
	15: ,
	15: ID, name= y
	15: )
	15: )
	15: ;
  16: }
	16: }
	17: EOF

Using flex

$ make cminus_flex
$ ./cminus_flex test.cm

Overview

flex ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ C-Minus์˜ lexer๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๊ณ  ์‚ฌ์šฉํ•œ๋‹ค.

๊ณผ์ œ์ˆ˜ํ–‰

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ข…์†์„ฑ์„ ์—†์• ๊ธฐ ์œ„ํ•ด noyywrap ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋„๋ก cminus.l์—์„œ ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

%option noyywrap

Makefile ์— ์•„๋ž˜ ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•œ๋‹ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ข…์†์„ฑ์„ ์ œ๊ฑฐํ•˜์˜€๊ธฐ ๋•Œ๋ฌธ์— -l ์˜ต์…˜์ด ํ•„์š” ์—†๋‹ค.

cminus_flex: main.o globals.h util.o lex.yy.o
        $(CC) $(CFLAGS) main.o util.o lex.yy.o -o cminus_flex

lex.yy.o: cminus.l scan.h util.h globals.h
        flex -o lex.yy.c cminus.l
        $(CC) $(CFLAGS) -c lex.yy.c

lex/tiny.l์„ ๊ธฐ๋ฐ˜์œผ๋กœ cminus.l์„ ์ž‘์„ฑํ•œ๋‹ค. ํŽธ๋ฆฌํ•œ ๋ฌธ๋ฒ•์„ ์ œ๊ณตํ•ด ์ฃผ์–ด์„œ ๋ณ„๋‹ค๋ฅธ ์–ด๋ ค์›€ ์—†์ด cminus์˜ ๋ฌธ๋ฒ•๋“ค์„ ๊ตฌํ˜„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

Results

TINY COMPILATION: test.cm
	4: reserved word: int
	4: ID, name= gcd
	4: (
	4: reserved word: int
	4: ID, name= u
	4: ,
	4: reserved word: int
	4: ID, name= v
	4: )
	5: {
	6: reserved word: if
	6: (
	6: ID, name= v
	6: ==
	6: NUM, val= 0
	6: )
	6: reserved word: return
	6: ID, name= u
	6: ;
	7: reserved word: else
	7: reserved word: return
	7: ID, name= gcd
	7: (
	7: ID, name= v
	7: ,
	7: ID, name= u
	7: -
	7: ID, name= u
	7: /
	7: ID, name= v
	7: *
	7: ID, name= v
	7: )
	7: ;
	9: }
	11: reserved word: void
	11: ID, name= main
	11: (
	11: reserved word: void
	11: )
	12: {
	13: reserved word: int
	13: ID, name= x
	13: ;
	13: reserved word: int
	13: ID, name= y
	13: ;
	14: ID, name= x
	14: =
	14: ID, name= input
	14: (
	14: )
	14: ;
	14: ID, name= y
	14: =
	14: ID, name= input
	14: (
	14: )
	14: ;
	15: ID, name= output
	15: (
	15: ID, name= gcd
	15: (
	15: ID, name= x
	15: ,
	15: ID, name= y
	15: )
	15: )
	15: ;
	16: }
	17: EOF

Review

tiny์˜ ์†Œ์Šค๊ฐ€ ๋ฏธ๋‹ˆ๋ฉ€ํ•˜๊ฒŒ ์ž˜ ์งœ์ ธ ์žˆ์–ด์„œ ๊ณผ์ œ๋Š” ๋ณ„๋‹ค๋ฅธ ์–ด๋ ค์›€ ์—†์ด ์ˆ˜ํ–‰ ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์ด๋ฒˆ ๊ณผ์ œ์˜ ์•„์‰ฌ์šด ์  ์ด๋ผ๋ฉด ๊ธฐ๊ป ์ƒˆ๋กœ์šด ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์ œ์ž‘ํ•˜๋Š”๋ฐ C์˜ Subset์ธ ์–ธ์–ด๋ฅผ ๋งŒ๋“ ๋‹ค๋Š” ์ ์ด๋‹ค. ์ด ์–ธ์–ด๋Š” ์•„๋ฌด๋ฆฌ ์ž˜ ๋งŒ๋“ค์–ด๋ด์•ผ C์˜ ํ•˜์œ„ ํ˜ธํ™˜์ด๊ณ  ๋ณ„๋‹ค๋ฅธ ์“ธ๋ชจ๊ฐ€ ์—†์–ด ๋ณด์ธ๋‹ค. ์ฐจ๋ผ๋ฆฌ DSL(Domain-Specific Language)๋ฅผ ํ•˜๋‚˜ ์ •์˜ํ•˜์—ฌ ์ง์ ‘ ๊ตฌํ˜„ํ•ด ๋ณด๊ฑฐ๋‚˜ ๋ฌธ๋ฒ•์ด ๊ฐ„๋‹จํ•˜๋ฉด์„œ๋„ First-Class Function์„ ์ง€์›ํ•˜๋Š” JavaScript๋ฅผ ์ง์ ‘ ๊ตฌํ˜„ํ•ด๋ณด๋ฉด ๋” ์žฌ๋ฐŒ๊ณ  ๋ณด๋žŒ์ฐฌ ๊ณผ์ œ๊ฐ€ ๋˜์ง€ ์•Š์•˜์„๊นŒ ํ•œ๋‹ค.

Project 2 - Parser

Overview

  • Flex๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•œ C-Minus Scanner๋ฅผ ์ด์šฉ
  • Yacc (bison)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์–ป์€ ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ํ•ฉํ•˜์—ฌ Parser๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.

How to use

$ make cminus
$ ./cminus test.cm
$ make test

BNF Grammer for C Minus

๊ตฌํ˜„ ๊ณผ์ •

main.c

Parser ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด ์ƒ์ˆ˜๋“ค์„ ์ˆ˜์ •ํ•˜์˜€๋‹ค. bison์„ ์‚ฌ์šฉ ํ•˜๊ธฐ ์œ„ํ•ด Global ๋ณ€์ˆ˜๋“ค์„ ์ˆ˜์ •ํ•˜์˜€๋‹ค.

#define NO_PARSE FALSE
int EchoSource = TRUE;
int TraceScan = FALSE;
int TraceParse = TRUE;

globals.h

yacc/globals.h ํŒŒ์ผ์„ ๋ณต์‚ฌํ•˜์—ฌ ์ˆ˜์ •ํ•˜์˜€๋‹ค. ํ† ํฐ๋“ค์˜ ์ •์˜๋ฅผ ๋ฐ›์•„์˜ค๊ธฐ ์œ„ํ•ด bison์—์„œ ์ƒ์„ฑ๋˜๋Š” y.tab.h๋ฅผ include ํ•˜์˜€๋‹ค.

Makefile

bison์„ ์‚ฌ์šฉํ•ด y.tab.c๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๊ณ  ์ปดํŒŒ์ผ ํ•˜๊ธฐ ์œ„ํ•ด Makefile์„ ์ˆ˜์ •ํ•˜์˜€๋‹ค.

# yacc์—์„œ token๋“ค์„ ์ •์˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€์žฅ ๋จผ์ € ์ปดํŒŒ์ผ ๋˜์–ด์•ผ ํ•œ๋‹ค.
# ์ปดํŒŒ์ผ ์—๋Ÿฌ๋ฅผ ๋ง‰๊ธฐ ์œ„ํ•ด, analyze.o, cgen.o๋ฅผ ์ปดํŒŒ์ผ ํ•˜์ง€ ์•Š๋Š”๋‹ค.
OBJS = y.tab.o lex.yy.o main.o util.o symtab.o

y.tab.o: cminus.y globals.h
	bison -d cminus.y --yacc
	$(CC) $(CFLAGS) -c y.tab.c

util.c & util.h

BNF์—์„œ Decl, Param, Type Node๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ์œผ๋ฏ€๋กœ ์ด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ ๋‹ค.

๋˜ํ•œ ์ƒ์„ฑ๋œ parse tree๋ฅผ ์ถœ๋ ฅ ํ•  ์ˆ˜ ์žˆ๋„๋ก printTree๋ฅผ ์ˆ˜์ •ํ•˜์˜€๋‹ค.

cminus.y

yacc/tiny.y ํŒŒ์ผ์„ ๋ณต์‚ฌํ•˜์—ฌ ์ˆ˜์ •ํ•˜์˜€๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๋ฌธ๋ฒ•๋“ค์€ tiny์™€ ํฌ๊ฒŒ ๋‹ค๋ฅด์ง€ ์•Š์•„ ์ˆ˜์ •ํ•˜๋Š”๊ฒŒ ๋ณ„ ๋ฌธ์ œ๊ฐ€ ์—†์—ˆ์œผ๋‚˜, ID(๋ณ€์ˆ˜๋ช…์ด๋‚˜ ํ•จ์ˆ˜๋ช…)์„ ๊ฐ€์ ธ์™€์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ID๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด ๋ณ„๋„์˜ ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜์˜€๋‹ค. ๋งˆ์ง€๋ง‰ ํ† ํฐ๋งŒ ์ €์žฅํ•˜๋ฏ€๋กœ, ๋’ค์˜ ํ† ํฐ์„ ์ฒ˜๋ฆฌํ•ด ๋ฒ„๋ฆฌ๋ฉด token์ด ๋‚ ์•„๊ฐ€๋ฒ„๋ ค identifier๋ฅผ ์ฝ์„ ์ˆ˜ ์—†๋Š” ๊ฒƒ์ด๋‹ค.

saveName    : ID
                 { savedName = copyString(tokenString);
                   savedLineNo = lineno;
                 }

saveNumber  : NUM
                 { savedNumber = atoi(tokenString);
                   savedLineNo = lineno;
                 }

์œ„ ๋‘ ๋ฌธ๋ฒ•์„ ์ถ”๊ฐ€๋กœ ์ •์˜ํ•˜์—ฌ, ID์™€ NUM์„ ์‚ฌ์šฉ ํ•˜๋Š” ๊ณณ์„ ๋Œ€์ฒดํ•˜์—ฌ ์‚ฌ์šฉํ•˜์˜€๋‹ค.

var_decl    : type_spec saveName SEMI
                 { $$ = newDeclNode(VarK);
                   $$->child[0] = $1; /* type */
                   $$->lineno = lineno;
                   $$->attr.name = savedName;

saveName์„ ์ด์šฉํ•ด ID๋ฅผ ๋ณ„๋„๋กœ ์ €์žฅํ•ด๋‘์—ˆ๋‹ค๊ณ  ํ•ด๋„ ์ €์žฅํ•˜๋Š” ๋ณ€์ˆ˜๊ฐ€ global variable์ด๋‹ค ๋ณด๋‹ˆ ๋ฎ์–ด์จ์ง€๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— saveName์ดํ›„ ๋˜ saveName์„ ์‚ฌ์šฉ ํ•  ๊ฒฝ์šฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€๋‹ค. saveName์— stack์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ํ•˜๋‚˜์”ฉ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅ ํ•˜๊ฒ ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์˜€์ง€๋งŒ, ๊ตณ์ด stack์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ํ•ด๊ฒฐ ๊ฐ€๋Šฅํ•œ ๋ฌธ์ œ์˜€๊ธฐ์— ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜๋‹ค. saveName์„ ์ด์šฉํ•˜๋”๋ผ๋„ ๋ฐ”๋กœ ํŒŒ์‹ฑ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•˜๋„๋ก ๋ณ€๊ฒฝํ•˜์—ฌ, savedName์ด ๋ฎ์–ด์จ์ง€๋Š” ๊ฒฝ์šฐ๋ฅผ ๋ฐฉ์ง€ํ•˜์˜€๋‹ค. ์•„๋ž˜ ์˜ˆ์ œ์˜ ๊ฒฝ์šฐ saveName ๋ฐ”๋กœ ๋’ค์—์„œ name์„ ์ €์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด args์•ˆ์—์„œ savedName์„ ๋ฎ์–ด์“ฐ๊ธฐ ๋œ๋‹ค.

call        : saveName {
                 $$ = newExpNode(CallK);
                 $$->attr.name = savedName;
              }
              LPAREN args RPAREN
                 { $$ = $2;
                   $$->child[0] = $4;
                 }

bison ๋ฒ„์ „์˜ ๋ฌธ์ œ์ธ์ง€ yylex function์˜ ์„ ์–ธ์„ ์ฐพ์ง€ ๋ชปํ•ด ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒ, cminus.y ์˜ ์ƒ๋‹จ์— yylex์„ ์„ ์–ธํ•ด์ฃผ์—ˆ๋‹ค.

static int yylex(void);

Results

1. test.cm

./cminus test.cm

TINY COMPILATION: test.cm

Syntax tree:
  Function Dec: gcd
    Type: int
    Parameter: u
      Type: int
    Parameter: v
      Type: int
    Compound Statment
      If
        Op: ==
          Id: v
          Const: 0
        Return
          Id: u
        Return
          Call(followings are args) : gcd
            Id: v
            Op: -
              Id: u
              Op: *
                Op: /
                  Id: u
                  Id: v
                Id: v
  Function Dec: main
    Type: void
    Compound Statment
      Var Dec: x
        Type: int
      Var Dec: y
        Type: int
      Assign
        Id: x
        Call(followings are args) : input
      Assign
        Id: y
        Call(followings are args) : input
      Call(followings are args) : output
        Call(followings are args) : gcd
          Id: x
          Id: y

๊ณผ์ œ ๋ช…์„ธ์˜ ์˜ˆ์ œ์™€ ๊ฒฐ๊ณผ๊ฐ€ ์กฐ๊ธˆ ๋‹ค๋ฅด์ง€๋งŒ, ํŒŒ์‹ฑ ์ด ์ •์ƒ์ ์œผ๋กœ ์ผ์–ด๋‚ฌ์Œ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ์ œ์™€ ๋‹ค๋ฅธ ๊ณณ์€ ์„ ์–ธ์—์„œ์˜ Type๋ถ€๋ถ„์ธ๋ฐ, type์€ cminus์—์„œ void์™€ int๋งŒ ์„ ์–ธํ•˜์—ฌ์„œ ๊ทธ๋ ‡์ง€ ์‹ค์ œ C์—์„  const, static ๋“ฑ์˜ ์ ‘๋‘์‚ฌ๊ฐ€ ๋ถ™์„ ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ™•์žฅ์„ฑ์„ ์œ„ํ•ด ํ•จ์ˆ˜ ์„ ์–ธ๊ณผ ๋ณ€์ˆ˜ ์„ ์–ธํ•ด์„œ type์„ child๋กœ ๊ฐ€์ง€๋„๋ก ํ•˜์˜€๋‹ค.

2. Array Test

BNF์ƒ์— array๊ฐ€ ์กด์žฌํ•˜๋Š”๋ฐ, test.cm์—์„œ array๋ฅผ ํ…Œ์ŠคํŠธ ํžˆ์ง€ ๋ชปํ•ด ์ถ”๊ฐ€์ ์ธ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•˜์˜€๋‹ค.

int aaa[1234];
int function (int a,int b, int c[], int d) { }
Syntax tree:
  Var Dec(following const:array length): aaa 1234
    Type: int
  Function Dec: function
    Type: int
    Parameter: a
      Type: int
    Parameter: b
      Type: int
    Array Parameter: c
      Type: int
    Parameter: d
      Type: int
    Compound Statment

Reviews

parse.c๋ฅผ ์ง์ ‘ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ์‰ฝ๋‹ค๊ณ  ์ด์•ผ๊ธฐ๋ฅผ ๋“ค์—ˆ์œผ๋‚˜, ์ถ”ํ›„ ์ง์ ‘ ๋‹ค๋ฅธ ์–ธ์–ด๋ฅผ ๋งŒ๋“ค์–ด ๋ณผ๋•Œ๋ฅผ ๋Œ€๋น„ํ•˜์—ฌ yacc๋ฅผ ์ตํ˜€๋‘๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ ๊ฐ™์•„ yacc๋ฅผ ์ด์šฉํ•˜์—ฌ ์ž‘์„ฑํ•˜์˜€๋‹ค. bison์ด BNF๋กœ ๋ฌธ๋ฒ•๋งŒ ์ •์˜ํ•˜๋ฉด ์•Œ์•„์„œ c code์˜ parser๋ฅผ ์ƒ์„ฑํ•ด์ฃผ๋Š” ๋งค์šฐ High ํ•œ ์ˆ˜์ค€์ธ์ง€ ์•Œ์•˜๋Š”๋ฐ, BNF์ž‘์„ฑ์œผ๋กœ ๋๋‚˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ tree์˜ ๋‚ด์šฉ๋“ค์„ ์ €์žฅํ•ด ์ฃผ๋Š” ๊ณผ์ •๋„ ํ•„์š”ํ•˜๋‹ค๋Š” ๊ฒƒ์— ๋†€๋žฌ๋‹ค. ํ•˜์ง€๋งŒ ํŽธ๋ฆฌํ•œ ๋„๊ตฌ์ž„์ด ๋ถ„๋ช…ํ•˜๋ฉฐ, bison์„ ์‚ฌ์šฉํ•ด ๋ณด์•˜๋‹ค๋Š” ๊ฒƒ ์ž์ฒด๊ฐ€ ์ด๋ฒˆ ๊ณผ์ œ๋ฅผ ํ†ตํ•ด ์–ป์€ ๊ฐ€์žฅ ํฐ ๊ฒฝํ—˜์ธ ๊ฒƒ ๊ฐ™๋‹ค.

Project 3 - Semantic Analysis

Overview

  • C-Minus์˜ Symbol Table ๊ตฌํ˜„
  • C-Minus์˜ Type Checker ๊ตฌํ˜„

How to use

$ make cminus
$ ./cminus test.cm
$ make cminus_flex
$ ./cminus_flex test.cm

Scope

  • Compound Statement๋ณ„ Scope ์ ์šฉ
  • ์„ ์–ธ๋˜์ง€ ์•Š์€ ๋ณ€์ˆ˜๊ฐ€ ์‚ฌ์šฉ๋˜๋ฉด ์—๋Ÿฌ
  • ๊ธฐ๋ณธํ•จ์ˆ˜๋Š” ํ•ญ์ƒ ํฌํ•จํ•˜๊ณ  ์žˆ์–ด์•ผ ํ•จ
    • int input(), void output(int arg)

Type Checker

โ€“ void๋Š” ํ•จ์ˆ˜์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ โ€“ return type ํ™•์ธ โ€“ Assignํ•  ๋•Œ ๋‘ ํ”ผ์—ฐ์‚ฐ์ž(operand)์˜ ํƒ€์ž… ์ผ์น˜ ํ™•์ธ โ€“ Function Call ํ•  ๋•Œ argument ์ˆ˜ ํ™•์ธ

  • If๋‚˜ While์˜ Expression์ด ๊ฐ’์„ ๊ฐ€์ง€๋Š”์ง€ ํ™•์ธ
  • ๊ทธ ์™ธ ๋‹ค๋ฅธ ์—ฌ๋Ÿฌ ๊ฐ€์ง€๋ฅผ C-Minus ๋ฌธ๋ฒ•์„ ์ฐธ์กฐํ•˜์—ฌ ํ™•์ธ

๊ตฌํ˜„๊ณผ์ •

main.c

Semantic Analysis๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด main.c์˜ ์˜ต์…˜์„ ์ˆ˜์ •ํ•˜์˜€๋‹ค.

#define NO_ANALYZE FALSE
int TraceParse = FALSE;
int TraceAnalyze = TRUE;

symtab.c & symtab.h

BucketList๋ฅผ Wrapping ํ•˜๋Š” Scope ๊ตฌ์กฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

typedef struct ScopeRec
   { char * funcName;
     int nestedLevel;
     struct ScopeRec * parent;
     BucketList hashTable[SIZE]; /* the hash table */
   } * Scope;

Static Scope๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด Scope๋ฅผ Stack ํ˜•ํƒœ๋กœ ๊ด€๋ฆฌ ํ•˜๋Š” Function๋“ค์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

Scope sc_top( void );
void sc_pop( void );
void sc_push( Scope scope );

Analyze๋ฅผ ๋•๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

analyze.c & analyze.h

Compound State๋ฅผ ์ถ”๊ฐ€ ํ•  ๋•Œ ๋งˆ๋‹ค ์ƒˆ๋กœ์šด Scope๋ฅผ ๋งŒ๋“ค์–ด Stack์— Push ํ•ฉ๋‹ˆ๋‹ค. Scopmpound State๋ฅผ ๋น ์ ธ๋‚˜๊ฐˆ๋•Œ Stack์„ Pop ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ, Function์˜ ๊ฒฝ์šฐ argument๋“ค๊ณผ Declaration์˜ Scope๊ฐ€ ๊ฐ™๋„๋ก ์ฃผ์˜ํ•ฉ๋‹ˆ๋‹ค.

์ƒˆ๋กœ์šด ์„ ์–ธ์ด ์žˆ์„ ๋•Œ๋Š” ํ˜„์žฌ์˜ Scope์™€ ๊ฒ€์‚ฌํ•˜์—ฌ ์ค‘๋ณต์ด ์žˆ๋Š”์ง€๋ฅผ ํ™•์ธ, ์ค‘๋ณต์ด ์žˆ์œผ๋ฉด ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ Scope์˜ Stack์„ ๊ฐ€๊นŒ์šด ์ˆœ์„œ๋Œ€๋กœ ๊ฒ€์ƒ‰ํ•˜์—ฌ ๋ณ€์ˆ˜๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ , ์—†์œผ๋ฉด ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

Input, Output Function์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. line number๋Š” -1๋กœ ์„ค์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๋ช…์„ธ์— ์ฃผ์–ด์ง„๋Œ€๋กœ Type๋“ค์„ ์ฑ„ํฌํ•ฉ๋‹ˆ๋‹ค.

์ˆ˜ํ–‰๊ฒฐ๊ณผ

test.cm

./cminus test.cm

TINY COMPILATION: test.cm

Building Symbol Table...

Symbol table:

<global scope> (nested level: 0)
Symbol Name    Sym.Type  Data Type    Line Numbers
-------------  --------  -----------  ------------
main           Function  Void           11
input          Function  Integer        -1   14   14
output         Function  Void           -1   15
gcd            Function  Integer         4    7   15

function name: gcd (nested level: 1)
Symbol Name    Sym.Type  Data Type    Line Numbers
-------------  --------  -----------  ------------
u              Variable  Integer         4    6    7    7
v              Variable  Integer         4    6    7    7    7

function name: main (nested level: 1)
Symbol Name    Sym.Type  Data Type    Line Numbers
-------------  --------  -----------  ------------
x              Variable  Integer        13   14   15
y              Variable  Integer        13   14   15


Checking Types...


Type Checking Finished

Nested Scope

if compound ์•ˆ์˜ scope์™€ function์˜ scope๊ฐ€ ๋‹ฌ๋ผ์ง์„ ํ™•์ธ

int scope (int a) {
  if (a==1){
    int a;
    output(a);
  }
}
./cminus scope.cm

TINY COMPILATION: scope.cm

Building Symbol Table...

Symbol table:

<global scope> (nested level: 0)
Symbol Name    Sym.Type  Data Type    Line Numbers
-------------  --------  -----------  ------------
scope          Function  Integer         1
input          Function  Integer        -1
output         Function  Void           -1    4

function name: scope (nested level: 1)
Symbol Name    Sym.Type  Data Type    Line Numbers
-------------  --------  -----------  ------------
a              Variable  Integer         1    2

function name: scope (nested level: 2)
Symbol Name    Sym.Type  Data Type    Line Numbers
-------------  --------  -----------  ------------
a              Variable  Integer         3    4


Checking Types...

Type Checking Finished

void ํƒ€์ž…์˜ ๋ณ€์ˆ˜

void a;
Symbol error at line 1: variable should have non-void type
(Table ์ƒ๋žต)

return type

void func(void) {
  return 1;
}
(Table ์ƒ๋žต)
Type error at line 2: expected no return value

Reviuew

์ €๋ฒˆ ๊ณผ์ œ์ธ Syntax Analysis๊นŒ์ง€๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋ก ์—์„œ๋„ ๊ตฌํ˜„ ํ•ด๋ณด์•˜๋˜ ๋‚ด์šฉ์ด์—ˆ์ง€๋งŒ, Semantic Analysis๋ฅผ ์‹ค์ œ๋กœ ๊ตฌํ˜„ํ•ด ๋ณด๋Š” ๊ฒƒ์€ ์ฒ˜์Œ์ด๋ผ ์‹œํ–‰์ฐฉ์˜ค๊ฐ€ ๋งŽ์•˜๋‹ค. scope๋Š” stack๊ตฌ์กฐ๋กœ๋งŒ ๋ฐ”๊ฟ”์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋˜์„œ ํฐ ์–ด๋ ค์›€์ด ์—†์—ˆ์ง€๋งŒ type check์˜ ๊ฒฝ์šฐ flex, bison ๊ณผ ๊ฐ™์€ ์™ธ๋ถ€ ํˆด์˜ ๋„์›€๋„ ๋ฐ›์„ ์ˆ˜ ์—†์ด ๋ฐ”๋กœ c์˜ switch case๋กœ ๊ตฌํ˜„ ํ•˜๋ ค๋‹ˆ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ์ƒ๊ฐํ•˜์—ฌ์•ผ ํ•ด์„œ ํ˜ผ๋ž€์Šค๋Ÿฌ์› ๋‹ค. ๋ฌธ๋ฒ•์—๋Ÿฌ๊ฐ€ ์—ฐ์†์œผ๋กœ ๋ฐœ์ƒ ํ•  ๊ฒฝ์šฐ ์ƒ๊ฐ์น˜ ๋ชปํ•œ ์˜ˆ์™ธ๋กœ Segfault๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ๋„ ํ•˜๋Š” ๋“ฑ ๊ณ ๋ คํ•  ์‚ฌํ•ญ์ด ๋งŽ์•˜๋‹ค. ์—๋Ÿฌ ์ฒ˜๋ฆฌ๋ฅผ ์ž˜ ํ•ด์ฃผ๋Š” ํ˜„๋Œ€์˜ ์ปดํŒŒ์ผ๋Ÿฌ ์ œ์ž‘์ž๋“ค์—๊ฒŒ ๊ฐ์‚ฌํ•˜๋ฉฐ ๊ณผ์ œ๋ฅผ ๋งˆ๋ฌด๋ฆฌ ํ•ฉ๋‹ˆ๋‹ค.

Project 4 - Code Generation

Overview

  • ๊ธฐ์กด๊ณผ์ œ๋ฅผ ํ† ๋Œ€๋กœ ํ•˜์—ฌ Tiny Machine์—์„œ ๋™์ž‘ํ•˜๋Š” Code ์ƒ์„ฑ

How to use

$ make cminus
$ ./cminus test.cm

Tiny Instruction

(๊ทธ๋ฆผ)

Stack ๊ธฐ๋ฐ˜์˜ ๋ฉ”๋ชจ๋ฆฌ ํ™˜๊ฒฝ์„ ๊ฐ€์ง„๋‹ค.

  • Function Call์ด ์ผ์–ด๋‚˜๋ฉด local variable, parameters, return address, function address๊ฐ€ ์ฐจ๋ก€๋กœ ์Œ“์ธ๋‹ค.
  • ์ฆ‰, function pointer๋ฅผ fp๋ผ๊ณ  ํ•  ๋•Œ
    • fp-1 : return address
    • fp-2 : 1st parameter
    • fp-3 : 2nd parameter
    • ...
    • fp-n : last parameter
    • fp-n-1 : 1st local variable
    • fp-n-2 : 2nd local variable
    • ...

๊ตฌํ˜„๊ณผ์ •

main.c

Code Generation์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด flag๋ฅผ ์ˆ˜์ •

#define NO_CODE FALSE
int TraceAnalyze = FALSE;
int TraceCode = TRUE;

analyze.c & symtab.c & symtab.h

์ง€๋‚œ ๊ณผ์ œ์—์„œ๋Š” location์„ scope์˜ ๊นŠ์ด๋กœ ์ •์˜ํ•˜์˜€์—ˆ์ง€๋งŒ, ์ด๋ฒˆ์—๋Š” scope๋‚ด์˜ ๋ณ€์ˆ˜์˜ ์œ„์น˜๋กœ ๋ณ€๊ฒฝํ•˜์˜€๋‹ค. function pointer๋ฅผ fp๋ผ๊ณ  ํ•  ๋•Œ fp-2-loc์— ๋ณ€์ˆ˜๊ฐ€ ์ €์žฅ๋˜๊ฒŒ ๋œ๋‹ค.

code.c & code.h

์ˆ˜์ • ์—†์Œ

cgen.c

syntaxTree๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๊ฐ tree์˜ ํƒ€์ž…๋ณ„๋กœ genStmt, genExp, genDecl, genParam ์ด๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ๊ฐ๊ฐ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

genStmt
  • If, While : tiny์˜ ์ฝ”๋“œ๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ
  • Compound : Scope๋ฅผ ์ถ”๊ฐ€ํ•ด ์คŒ
  • Return : return address(fp-1)๋กœ expression ๊ฐ’์„ ๋‚ด๋ณด๋ƒ„
getExp
  • OP, Const : tiny์˜ ์ฝ”๋“œ๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ
  • Id : Scope๋ฅผ ๊ณ ๋ คํ•˜์—ฌ ๋ณ€์ˆ˜์˜ ์ฃผ์†Œ ๊ฐ’์„ ๊ณ„์‚ฐ
  • Assign : lhs(lvalue)๋Š” ์ฃผ์†Œ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ , rhs(rvalue)๋Š” ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๋„๋ก ๊ตฌํ˜„
  • Call : ํ•จ์ˆ˜์ฝœ์ด ์ผ์–ด๋‚ ๋•Œ Call Stack์— ํŒŒ๋ผ๋ฉ”ํ„ฐ, return value๊ฐ€ ์Œ“์ด๋Š” ์ˆœ์„œ์— ์ฃผ์˜ํ•˜์—ฌ ๊ตฌํ˜„
getDecl & getParam
  • Func, Var, ArrVar : ์ด์ „๋‹จ๊ณ„์—์„œ ํƒ€์ž…๊ณผ ์Šค์ฝ”ํ”„๋Š” ๊ฒ€์‚ฌํ•˜์˜€์œผ๋ฏ€๋กœ ํ• ๋‹น๋  ๋ฉ”๋ชจ๋ฆฌ ํฌ๊ธฐ๋งŒ ๊ณ„์‚ฐํ•œ๋‹ค. c-minus์—์„œ๋Š” ๋ชจ๋“  ๋ณ€์ˆ˜ํƒ€์ž…์ด 1์˜ ํฌ๊ธฐ๋ฅผ ๊ฐ€์ง€๋„๋ก ์„ค์ •ํ•˜์˜€๋‹ค. Array์˜ ๊ฒฝ์šฐ Array์˜ ํฌ๊ธฐ๋งŒํผ ํ• ๋‹น
getMainCall

syntaxTree๋ฅผ ๋Œ์•„ code๋ฅผ ์ƒ์„ฑํ•œ ํ›„, main๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑ

์ˆ˜ํ–‰๊ฒฐ๊ณผ

test.cm (์ „์ฒด ์ฝ”๋“œ๋Š” ์†Œ์ŠคํŒŒ์ผ๊ณผ ํ•จ๊ป˜ ์ฒจ๋ถ€ ๋˜์–ด ์žˆ์Œ)

/* A Program to perform Euclid`s
   Algorithm to computer gcd */

int gcd (int u, int v)
{
    if (v == 0) return u;
    else return gcd(v,u-u/v*v);
    /* u-u/v*v == u mod v */
}

void main(void)
{
    int x; int y;
    x = input(); y = input();
    output(gcd(x,y));
}
* TINY Compilation to TM Code
* File: test.tm
* Standard prelude:
  0:     LD  5,0(0) 	load gp with maxaddress
  1:    LDA  6,0(5) 	copy gp to mp
  2:     ST  0,0(0) 	clear location 0
* End of standard prelude.
* -> Function (gcd)
  4:     ST  1,-2(5) 	func: store the location of func. entry
* func: unconditional jump to next declaration belongs here
* func: function body starts here
  3:    LDC  1,6(0) 	func: load function location
  6:     ST  0,-1(6) 	func: store return address
* -> param
* u
* <- param
* -> param
* v
* <- param
* -> compound
* -> if
* -> Op
* -> Id (v)
  7:    LDC  0,-3(0) 	id: load varOffset
  8:    ADD  0,6,0 	id: calculate the address
  9:     LD  0,0(0) 	load id value
* <- Id
 10:     ST  0,-4(6) 	op: push left
* -> Const
 11:    LDC  0,0(0) 	load const
* <- Const
 12:     LD  1,-4(6) 	op: load left
 13:    SUB  0,1,0 	op ==
 14:    JEQ  0,2(7) 	br if true
 15:    LDC  0,0(0) 	false case
 16:    LDA  7,1(7) 	unconditional jmp
 17:    LDC  0,1(0) 	true case
...

ํ•จ์ˆ˜๋“ค๊ณผ ํŒŒ๋ผ๋ฉ”ํ„ฐ๋“ค์ด ์ž˜ ์ •์˜๋˜์–ด ํ˜ธ์ถœ๋˜๊ณ , ๋ณ€์ˆ˜๋“ค์˜ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ๋„ ์ œ๋Œ€๋กœ ๊ณ„์‚ฐ ๋จ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

Reviuew

๋“œ๋””์–ด ์ปดํŒŒ์ผ๋Ÿฌ์˜ ๋งˆ์ง€๋ง‰ ๊ณผ์ œ๊ฐ€ ๋๋‚ฌ์Šต๋‹ˆ๋‹ค. ๋จธ์‹ ์ฝ”๋“œ๋‚˜ LLVM ๋ ˆ๋ฒจ๊นŒ์ง€ ์ปดํŒŒ์ผ์ด ๋˜์–ด์„œ ์ง์ ‘ ์‹คํ–‰ ์‹œํ‚ฌ ์ˆ˜ ์žˆ์„์ง€ ์•Œ์•˜๋Š”๋ฐ, tiny machine ์šฉ์œผ๋กœ๋งŒ ์ปดํŒŒ์ผ์ด ๋˜์–ด ์กฐ๊ธˆ ์•„์‰ฝ์Šต๋‹ˆ๋‹ค๋งŒ ์ปดํŒŒ์ผ๋œ ์–ธ์–ด๊ฐ€ ์–ด์Ž”๋ธ”๋ฆฌ์–ด์— ๊ฐ€๊น๊ธฐ์— ์–ด์Ž”์œผ๋กœ์˜ ์ปดํŒŒ์ผ์„ ๊ฒฝํ—˜ํ•ด ๋ณผ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์žฅ๊ธฐ๊ฐ„ ์ง„ํ–‰๋œ ํ”„๋กœ์ ํŠธ์ž„์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์•„์‰ฝ๊ฒŒ๋„ ์‹ค์šฉ์ ์ธ ์–ธ์–ด๊ฐ€ ์•„๋‹ˆ๋ผ์„œ ์ด ํ”„๋กœ์ ํŠธ๋ฅผ ๋‹ค๋ฅธ ๊ณณ์—์„œ ์“ธ ์ˆ˜๋Š” ์—†๊ฒ ์ง€๋งŒ ํ•œ ํ•™๊ธฐ๋™์•ˆ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ ์‹ค์ œ๋กœ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๊ฐ€ ์–ด๋– ํ•œ ๊ณผ์ •์„ ๊ฑฐ์ณ์„œ ๋ถ„์„๋˜๋Š”์ง€๋ฅผ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ํŠนํžˆ ๋งˆ์ง€๋ง‰ ๊ณผ์ œ์—์„œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋ฅผ ๋ ˆ์ง€์Šคํ„ฐ๋ฆฌ ๋ช…๋ น๋‹จ์œ„๊นŒ์ง€ ์ปดํŒŒ์ผ์„ ํ•ด๋ณด๋ฉด์„œ, c์–ธ์–ด์—์„œ ์ž‘์„ฑ๋œ ์ฝ”๋“œ ํŠนํžˆ ํ•จ์ˆ˜ ํ˜ธ์ถœ์ด ์‹ค์ œ๋กœ ์ปดํ“จํ„ฐ๋‚ด์—์„œ ์–ด๋– ํ•œ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๋Š”์ง€ ๋‹ค์‹œ ํ•œ๋ฒˆ ์ตํž ์ˆ˜ ์žˆ์—ˆ๋‹ค.

์‹œํ—˜๊ธฐ๊ฐ„์ด๋ผ ์‹œ๊ฐ„์— ์ซ’๊ธฐ๋ฉฐ ๋งˆ๋ฌด๋ฆฌ ํ•˜๊ฒŒ ๋˜์—ˆ๋Š”๋ฐ, ๊ทธ๋ž˜๋„ ์ž˜ ๋งˆ๋ฌด๋ฆฌ ๋œ ๊ฒƒ ๊ฐ™์•„์„œ ๋‹คํ–‰์ž…๋‹ˆ๋‹ค. ํ•œํ•™๊ธฐ ๋™์•ˆ ๊ต์ˆ˜๋‹˜๊ณผ ์กฐ๊ต๋‹˜ ์ˆ˜๊ณ ํ•˜์…จ์Šต๋‹ˆ๋‹ค.

About

Subsets of C language

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •