이번에 프로그래밍 언어론을 듣습니다. 그 첫 번째 과제로 Lex & Yacc를 이용하여 간단한 공학용 계산기를 만드는 것입니다. 사칙연산뿐만 아니라 변수도 저장할 수 있어야 하고 사용자 함수 역시 저장할 수 있어야 합니다.
사용자 함수의 경우 구현하기가 조금 까다로워서 Flex와 Bison에서 제공하는 Recursive parser를 이용하여 처리하였습니다. 이 부분이 조금 어려웠고 처음 사용하는 것이라 코드가 이상해졌지만 그래도 문제 없이 돌아가는 것을 확인하였습니다.
engcalc.l
1: %{2: #include <stdio.h>3: #include <stdlib.h>4: #include "engcalc.tab.h"5: #include "recursive_parsing.h"6:7: // 재귀적인 parser 호출을 위한 코드8: /*9: When in the lexer you have to access parm through the extra data.10: */11: #define PARM yyget_extra(yyscanner)12:13: /*14: ** We want to read from a the buffer in parm so we have to redefine the15: ** YY_INPUT macro (see section 10 of the flex manual 'The generated scanner')16: */17: #define YY_INPUT(buffer, res, max_size) \18: do { \19: if (PARM->pos >= PARM->length) \20: res = YY_NULL; \21: else \22: { \23: res = PARM->length - PARM->pos; \24: res > (int)max_size ? res = max_size : 0; \25: memcpy(buffer, PARM->buf + PARM->pos, res); \26: PARM->pos += res; \27: } \28: } while (0)29:30: // 재귀적인 parsing 호출을 위한 코드31: %}32:33: /*34: ** We want the scanner to be reentrant, therefore generate no global variables.35: ** That what the 'reentrant' option is for.36: ** 'bison-bridge' is used to create a bison compatible scanner and share yylval37: */38: %option reentrant bison-bridge39: %option noyywrap40: %option nounput41:42: LETTER [A-Za-z]43: DIGIT [0-9]44:45: %%46:47: [ \t]+ ; /* whitespace */48:49: "=" { return EQU_T; }50:51: "+" { return OP1; } /* token binop '+' */52: "-" { return OP2; } /* token binop '-' */53: "*" { return OP3; } /* token binop '*' */54: "/" { return OP4; } /* token binop '/' */55: "^" { return OP5; } /* token binop '^' */56: "#" { return OP6; } /* token binop '#' */57: "(" { return SMALLPL_T; }58: ")" { return SMALLPR_T; }59: "[" { return BIGPL_T; }60: "]" { return BIGPR_T; }61:62: "sin" { return SIN; }63: "cos" { return COS; }64: "tan" { return TAN; }65: "log" { return LOG; }66: "ln" { return LN; }67: "exp" { return EXP; }68: "clear" { return CLEAR; }69: "clearf" { return CLEARF; }70: "exit" { return EXIT; }71: "\n" { return EOL; }72:73: "("({LETTER})({LETTER}|{DIGIT}|_|,|[ ])*")"[ ]*"="[ ]*({LETTER}|{DIGIT}|_|\+|\-|\*|\/|\^|\#|[ ]|\(|\))+ { yylval->TT_SYMT = strndup(yytext, yyleng); return FUNC_T; } // function parameter and body74: "("({LETTER}|{DIGIT}|_|,|[ ])*")" { yylval->TT_SYMT = strndup(yytext, yyleng); return FUNC_ARG_T; } // function argument to use function call75:76: ({LETTER})({LETTER}|{DIGIT}|_)* { yylval->TT_SYMT = strndup(yytext, yyleng); return SYMT; } /* token id */77: ({DIGIT}+|{DIGIT}+\.{DIGIT}+)([eE][+-]?{DIGIT}+)? { yylval->TT_NUMBER = atof(yytext); return NUMBER; } /* token real number */78:79: . yyerror(); // All other character is not understood by scanner, so call error function.80: %%81:82:83:
engcalc.y
1: %{2: // include whole header file to use this code.3: #include <stdio.h>4: #include <stdlib.h>5: #include <string.h>6: #include <math.h>7:8: #include "recursive_parsing.h"9: #include "symboltable.h"10:11: #define PI 3.1415926512:13: extern SymbolTable* SymTab; // SymTab Linked List14: static int Error_Flag = 0; // Error 시 결과를 얘기하기 위한 전역변수15:16: // declare function17: double my_sin(double x);18: double my_cos(double x);19: double my_tan(double x);20: double user_func_evaluate(char* func_name, char* func_arg);21: void user_func_define(char* func_name, char* func_all);22: extern void parse(char *buf, double *result);23:24: %}25:26: %pure_parser27: %parse-param {parse_parm *parm}28: %parse-param {void *scanner}29: %lex-param {yyscan_t *scanner}30:31: %union32: {33: double TT_NUMBER;34: char* TT_SYMT;35:36: /* Non Terminal Type */37: int TT_Statement;38: double TT_Expression;39: double TT_Exp_func;40: double (*TT_BuiltFunc)();41: };42:43: %token <TT_SYMT> SYMT /* id */44: %token <TT_SYMT> FUNC_ARG_T /* function real argument */45: %token <TT_SYMT> FUNC_T /* function parameter and body */46: %token <TT_NUMBER> NUMBER /* integer */47: %token OP1 /* '+' */48: %token OP2 /* '-' */49: %token OP3 /* '*' */50: %token OP4 /* '/' */51:52: %token SMALLPL_T /* ( */53: %token SMALLPR_T /* ) */54: %token EQU_T /* = */55: %token BIGPL_T /* [ */56: %token BIGPR_T /* ] */57:58:59: %token SIN /* sin() */60: %token COS /* cos() */61: %token TAN /* tan() */62: %token LOG /* log() */63: %token LN /* ln() */64: %token EXP /* exp() */65:66: %token CLEAR /* clear */67: %token CLEARF /* clearf */68:69: %token EXIT /* exit command */70:71: %token EOL /* End of Line */72:73: %type <TT_Statement> Statement74: %type <TT_Expression> Expression75: %type <TT_BuiltFunc> BuiltFunc76: %type <TT_Exp_func> Exp_func77:78: /* 우선순위 */79: %right EQU_T /* = */80: %left OP1 OP2 /* + - */81: %left OP3 OP4 /* * / */82: %right OP5 OP6 /* ^ # */83: %nonassoc UMINUS /* unary operation */84: %left SMALLPL_T SMALLPR_T /* () */85:86:87: %start Goal // Start symbol is Program88:89: %%90: Goal: Statement EOL { } // 변수, 함수 생성 및 삭제91: | Expression EOL { // 그 외 여러 expression92: if(!Error_Flag)93: {94: printf("Ans : %f\n", $1);95: }96: else97: {98: Error_Flag = 0;99: }100: }101: | EXIT EOL { printf("Engineering Calculator Exit! Good Bye~\n"); exit(0); } // 종료102: | EQU_T Exp_func { // function define시 사용하는 코드103: }104: | Expression { // function call 시 함수 argument parsing105: parm->result = $1;106: }107: ;108:109: Statement: SYMT EQU_T Expression { // 변수 생성.110: SymbolTable* temp;111: if(NULL == (temp = Symbol_Search($1, 1)))112: {113: temp = malloc(sizeof(SymbolTable));114: if(NULL == temp)115: {116: printf("malloc error!\n");117: exit(1);118: }119: temp->name = $1;120: temp->num_value = $3;121: temp->type = 1; // 변수는 1122: temp->left_symbol = NULL;123: temp->right_symbol = NULL;124: Symbol_Insert(temp);125: printf("make variable %s = %f\n", $1, $3);126: }127: // 변수가 이미 있다면 값 변경.128: else129: {130: temp->num_value = $3;131: printf("Ans : %f\n", $3);132: }133: }134: | CLEAR BIGPL_T SYMT BIGPR_T { // 변수 삭제.135: if(-1 == Symbol_Delete($3, 1))136: printf("Error!! There is no variable named %s.\n", $3);137: else138: printf("delete %s variable\n", $3);139: }140: | CLEAR BIGPL_T BIGPR_T { // 모든 변수 삭제.141: Symbol_Delete_All(1);142: printf("delete all variable\n");143: }144: | SYMT FUNC_T { // 함수 생성.145: user_func_define($1, $2);146: }147: | CLEARF BIGPL_T SYMT BIGPR_T { // 함수 삭제148: if(-1 == Symbol_Delete($3, 2))149: printf("Error!! There is no function named %s.\n", $3);150: else151: printf("delete %s function\n", $3);152: }153: | CLEARF BIGPL_T BIGPR_T { // 모든 함수 삭제154: Symbol_Delete_All(2);155: printf("delete all functions\n");156: }157: ;158:159: Expression: Expression OP1 Expression { $$ = $1 + $3; } // 덧셈160: | Expression OP2 Expression { $$ = $1 - $3; } // 뺄셈161: | Expression OP3 Expression { $$ = $1 * $3; } // 곱셈162: | Expression OP4 Expression { // 나눗셈163: if(0.0 == $3)164: {165: printf("Error!! divide by zero\n");166: Error_Flag = 1;167: }168: else169: $$ = $1 / $3;170: }171: | Expression OP5 Expression { $$ = pow($1, $3); } // 승172: | Expression OP6 Expression { $$ = exp(log($3) / $1); } // 제곱근, http://www.daniweb.com/forums/thread12733.html173: | OP2 Expression %prec UMINUS { $$ = -$2; } // 음수174: | SMALLPL_T Expression SMALLPR_T { $$ = $2; } // 괄호175: | NUMBER { $$ = $1; } // 숫자176: | SYMT { // memory 변수 접근177: SymbolTable* symt = Symbol_Search($1, 1); // symboltable에 있는지 검색178:179: if(NULL != symt)180: {181: // 있다면 값을 반환182: $$ = symt->num_value;183: }184: else if(NULL != (symt = Symbol_Search($1, 3)))185: {186: // 있다면 값을 반환187: $$ = symt->num_value;188: }189: else190: {191: // 없다면 에러 메시지를 띄움.192: printf("Error!! There is no variable named %s.\n", $1);193: Error_Flag = 1;194: $$ = 0; // default로 0을 반환. 출력은 하지 않음.195: }196: }197: | BuiltFunc FUNC_ARG_T { // 미리 정의된 함수 사용.198: double parsed_argu;199: char temp_exp[MAX_CHAR];200: strncpy(temp_exp, &$2[1], (strlen($2)-2)); // 괄호 제거201: parse(temp_exp, &parsed_argu); // 괄호 안의 것 parsing202: $$ = ($1)(parsed_argu);203: }204: | SYMT FUNC_ARG_T { $$ = user_func_evaluate($1, $2); } // 사용자가 정의한 함수 사용205: ;206:207: BuiltFunc: SIN { $$ = my_sin; }208: | COS { $$ = my_cos; }209: | TAN { $$ = my_tan; }210: | LOG { $$ = log10; }211: | LN { $$ = log; }212: | EXP { $$ = exp; }213:214: Exp_func : Exp_func OP1 Exp_func {}215: | Exp_func OP2 Exp_func {}216: | Exp_func OP3 Exp_func {}217: | Exp_func OP4 Exp_func {}218: | Exp_func OP5 Exp_func {}219: | Exp_func OP6 Exp_func {}220: | OP2 Exp_func %prec UMINUS {}221: | SMALLPL_T Exp_func SMALLPR_T{}222: | NUMBER {}223: | SYMT { // 함수 정의 시 body 안에 심볼로 파라메터만 있는지 확인224: SymbolTable* temp = Symbol_Search($1, 4);225: if(NULL == temp)226: {227: printf("There is no %s named parameter.\n", $1);228: Symbol_Delete_All(1);229: Symbol_Delete_All(2);230: Symbol_Delete_All(3);231: Symbol_Delete_All(4);232: exit(1);233: }234: }235: | BuiltFunc FUNC_ARG_T {}236: %%237:238: // degree 계산을 위해 만든 함수239: double my_sin(double x)240: {241: return sin(x*PI/180);242: }243:244: // degree 계산을 위해 만든 함수245: double my_cos(double x)246: {247: return cos(x*PI/180);248: }249:250: // degree 계산을 위해 만든 함수251: double my_tan(double x)252: {253: return tan(x*PI/180);254: }255:256: // 유저가 만든 함수를 사용할 때 호출. 너무 길어서 따로 떼어냄.257: double user_func_evaluate(char* func_name, char* func_arg)258: {259: char temp_str[MAX_CHAR] = { 0 };260: double temp_func_arg[MAX_ARG_NUM] = { 0 };261: char* pch1;262: char* pch2;263: SymbolTable* temp_symt; // 변수 추가시 필요264: SymbolTable* symt = Symbol_Search(func_name, 2);// 이름으로 symboltable에서 함수 검색.265: double result; // 함수 실행 후 결과266: int i, j;267:268: if(NULL != symt)269: {270: // 함수가 있다면...271: // 들어온 func_arg를 parsing272: // func_arg를 배열에 저장273: i = 0;274: pch1 = strtok(&func_arg[1], ",");275:276: while(NULL != pch1)277: {278: if(NULL == (pch2 = strchr(pch1, ')')))279: {280: // 마지막 값이 아니라면281: parse(pch1, &temp_func_arg[i]);282: i++;283: pch1 = strtok(NULL, ",");284: }285: else286: {287: // 마지막이라면...288: pch2[0] = '\0';289: parse(pch1, &temp_func_arg[i]);290: pch2[0] = ')';291: break;292: }293: }294:295: // 함수의 parameter를 symboltable에 등록 type : 3296: i = 0;297: strcpy(temp_str, symt->str_func_value);298: pch1 = strtok(&temp_str[1], ",");299: while(NULL != pch1)300: {301: temp_symt = malloc(sizeof(SymbolTable));302: if(NULL == temp_symt)303: {304: printf("malloc error!\n");305: exit(1);306: }307:308: if(NULL == (pch2 = strchr(pch1, ')')))309: {310: // 마지막 값이 아니라면311: temp_symt->name = strndup(pch1, strlen(pch1));312: }313: else314: {315: // 마지막이라면...316: pch2[0] = '\0';317: temp_symt->name = strndup(pch1, strlen(pch1));318: pch2[0] = ')';319: }320: temp_symt->num_value = temp_func_arg[i];321: temp_symt->type = 3; // 함수 파라메터는 3322: temp_symt->left_symbol = NULL;323: temp_symt->right_symbol = NULL;324: Symbol_Insert(temp_symt);325:326: i++;327: pch1 = strtok(NULL, ",");328: }329:330: // 함수 본문 parsing331: strcpy(temp_str, symt->str_func_value);332: pch1 = strchr(temp_str, '='); // 함수 body 찾기333: parse(&pch1[1], &result);334:335: // symboltable에 함수 parameter 삭제336: Symbol_Delete_All(3);337:338: // 반환339: return result;340: }341: else342: {343: // 함수가 없다면 에러 메시지를 띄우고 반환344: printf("Error!! There is no function named %s.\n", func_name);345: Error_Flag = 1;346: return 0;347: }348: }349:350:351: void user_func_define(char* func_name, char* func_all)352: {353: SymbolTable* temp;354: char temp_str[MAX_CHAR] = { 0 };355: char* pch1;356: char* pch2;357: double result;358: int i;359: SymbolTable* temp_symt;360:361: // 함수 정의 여부 체크362: // 함수의 parameter를 symboltable에 등록 type : 4363: i = 0;364: strcpy(temp_str, func_all);365: pch1 = strtok(&temp_str[1], ",");366: while(NULL != pch1)367: {368: temp_symt = malloc(sizeof(SymbolTable));369: if(NULL == temp_symt)370: {371: printf("malloc error!\n");372: exit(1);373: }374:375: if(NULL == (pch2 = strchr(pch1, ')')))376: {377: // 마지막 값이 아니라면378: temp_symt->name = strndup(pch1, strlen(pch1));379: }380: else381: {382: // 마지막이라면...383: pch2[0] = '\0';384: temp_symt->name = strndup(pch1, strlen(pch1));385: pch2[0] = ')';386: }387: temp_symt->type = 4; // define시 함수 파라메터는 4388: temp_symt->left_symbol = NULL;389: temp_symt->right_symbol = NULL;390: Symbol_Insert(temp_symt);391:392: i++;393: pch1 = strtok(NULL, ",");394: }395:396: // 함수 본문 parsing397: strcpy(temp_str, func_all);398: pch1 = strchr(temp_str, '='); // 함수 body 찾기399: parse(pch1, &result);400:401: // symboltable에 함수 parameter 삭제402: Symbol_Delete_All(4);403:404: // 제대로 함수 등록405: // 함수가 이미 있는지 확인.406: if(NULL == (temp = Symbol_Search(func_name, 2)))407: {408: temp = malloc(sizeof(SymbolTable));409: if(NULL == temp)410: {411: printf("malloc error!\n");412: exit(1);413: }414: temp->name = func_name;415: temp->str_func_value = strndup(func_all, strlen(func_all));416: temp->type = 2; // 함수는 2417: temp->left_symbol = NULL;418: temp->right_symbol = NULL;419: Symbol_Insert(temp);420: printf("make function %s%s\n", func_name, func_all);421: }422: // 함수가 이미 있다면...423: else424: {425: free(temp->str_func_value);426: temp->str_func_value = strndup(func_all, strlen(func_all));427: printf("Ans : %s%s\n", func_name, func_all);428: }429: }
makefile
1: OBJS = engcalc.tab.o lex.yy.o main.o2:3: all: ${OBJS}4: gcc -o engcalc $? -lm -lfl -ly5:6: engcalc.tab.c: engcalc.y7: bison -d $?8:9: lex.yy.c: engcalc.l10: flex $?11:12: clean:13: rm -f engcalc engcalc.exe engcalc.tab.{c,h} lex.yy.c ${OBJS}14:15: .SUFFIXES: .c .o16:17: .c.o:18: gcc -c $< -o $*.o
recursive_parsing.h
- /*
- ** recursive_parsing.h
- */
- #ifndef __RECURSIVE_PARSING_H__
- #define __RECURSIVE_PARSING_H__
- typedef struct parse_parm_s
- {
- void *yyscanner; /* state of the lexer */
- char *buf; /* buffer we read from */
- int pos; /* current position in buf */
- int length; /* length of buf */
- double result;
- } parse_parm;
- typedef union
- {
- double TT_NUMBER;
- char* TT_SYMT;
- /* Non Terminal Type */
- int TT_Statement;
- double TT_Expression;
- double TT_Exp_func;
- double (*TT_BuiltFunc)();
- } parm_union;
- void parse(char *buf, double *result);
- #define YYSTYPE parm_union
- #define YY_EXTRA_TYPE parse_parm *
- /*
- ** forward declaration of lexer/parser functions
- ** so the compiler shuts up about warnings
- */
- int yylex(YYSTYPE *, void *);
- int yylex_init(void **);
- int yylex_destroy(void *);
- void yyset_extra(YY_EXTRA_TYPE, void *);
- int yyparse(parse_parm *, void *);
- void yyerror();
- #endif /* !__RECURSIVE_PARSING_H__ */
symboltable.h
- /*
- symboltable.h
- */
- #ifndef __SYMBOLTABLE_H__
- #define __SYMBOLTABLE_H__
- // SymboleTable Structure
- typedef struct SymbolTable
- {
- char* name;
- char* str_func_value;
- double num_value;
- int type; // º¯¼ö: 1, ÇÔ¼ö: 2
- struct SymbolTable* left_symbol;
- struct SymbolTable* right_symbol;
- } SymbolTable;
- #define MAX_CHAR 100
- #define MAX_ARG_NUM 10
- // ÇÔ¼ö¼±¾ð
- void Symbol_Insert(SymbolTable* symbol);
- SymbolTable* Symbol_Search(const char* name, const int type);
- int Symbol_Delete(const char* name, const int type);
- void Symbol_Delete_All(int type);
- void Symbol_Print_All(void);
- #endif /* !__SYMBOLTABLE_H__ */
main.c
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "recursive_parsing.h"
- #include "symboltable.h"
- void parse(char *buf, double *result);
- SymbolTable* SymTab; // SymTab Linked List
- // main ÇÔ¼ö
- int main(int argc, char* argv[])
- {
- char strinput[MAX_CHAR];
- double temp = 0;
- SymTab = NULL;
- printf("Engineering Calculator Start!\n");
- //yyparse(); // do parsing
- // »ç¿ëÀڷκÎÅÍÀÔ·ÂÀ»¹Þ½À´Ï´Ù.
- while(1)
- {
- printf("> ");
- fgets(strinput, 100, stdin);
- parse(strinput, &temp); // do parsing
- }
- return 0; // return to the OS
- }
- // SymbolTable¿¡»ðÀÔÇÏ´ÂÇÔ¼ö
- void Symbol_Insert(SymbolTable* symbol)
- {
- if(NULL != SymTab)
- {
- symbol->left_symbol = SymTab;
- symbol->right_symbol = SymTab->right_symbol;
- if(NULL != SymTab->right_symbol)
- {
- SymTab->right_symbol->left_symbol = symbol;
- }
- SymTab->right_symbol = symbol;
- }
- else
- {
- symbol->left_symbol = NULL;
- symbol->right_symbol = NULL;
- SymTab = symbol;
- }
- }
- // SymbolTable¿¡¼°Ë»öÇÏ´ÂÇÔ¼ö
- SymbolTable* Symbol_Search(const char* name, const int type)
- {
- SymbolTable* temp = SymTab; // ã±âÀ§Çغ¯¼ö¼³Á¤.
- // ³¡±îÁö°Ë»ö
- while(NULL != temp)
- {
- // ã´ÂÀ̸§ÀÌÁ¸ÀçÇÑ´Ù¸é
- if(temp->name && !strcmp(temp->name, name) && (type == temp->type))
- {
- return temp; // ÇØ´çsymbol ¹Ýȯ
- }
- temp = temp->right_symbol; // ã´ÂÀ̸§À̾ø±â¿¡´ÙÀ½°ÍÀ»¼³Á¤
- }
- return NULL;
- }
- // SymbolTable¿¡¼»èÁ¦ÇÏ´ÂÇÔ¼ö
- int Symbol_Delete(const char* name, const int type)
- {
- SymbolTable* target = Symbol_Search(name, type);
- // targetÀ̰¡ÀåóÀ½°ÍÀ̾ƴ϶ó¸é
- if(target != SymTab)
- {
- target->left_symbol->right_symbol = target->right_symbol; // left_symbolÀÌnullÀ̾ƴϹǷεû·Î°Ë»çÇÏÁö¾ÊÀ½.
- // °¡À峡¿¡ÀÖ´ÂsymbolÀϰæ¿ì
- if(NULL != target->right_symbol)
- target->right_symbol->left_symbol = target->left_symbol;
- }
- // targetÀ»Ã£¾ÒÀ¸³ª°¡ÀåóÀ½°Í
- else if(NULL != target)
- {
- SymTab = target->right_symbol;
- if(SymTab != NULL)
- SymTab->left_symbol = NULL;
- }
- // targetÀ»¸øÃ£Àº°æ¿ì
- else
- {
- return -1;
- }
- // Free
- free(target->name);
- // Áö¿ï´ë»óÀÌÇÔ¼ö¶ó¸évalue¸¦free
- if(2 == target->type)
- free(target->str_func_value);
- free(target);
- return 0;
- }
- // SymbolTable¸¦typeº°·Îºñ¿ì´ÂÇÔ¼ö.
- void Symbol_Delete_All(int type)
- {
- SymbolTable* target = SymTab; // Çϳª¾¿»èÁ¦¸¦À§Çغ¯¼ö¼³Á¤.
- SymbolTable* temp;
- // ³¡±îÁö°Ë»ö
- while(NULL != target)
- {
- // typeÀ̸´°¡?
- if(type == target->type)
- {
- // targetÀ̰¡ÀåóÀ½°ÍÀ̾ƴ϶ó¸é
- if(target != SymTab)
- {
- target->left_symbol->right_symbol = target->right_symbol; // left_symbolÀÌnullÀ̾ƴϹǷεû·Î°Ë»çÇÏÁö¾ÊÀ½.
- // °¡À峡¿¡ÀÖ´ÂsymbolÀϰæ¿ì
- if(NULL != target->right_symbol)
- target->right_symbol->left_symbol = target->left_symbol;
- }
- // targetÀ»Ã£¾ÒÀ¸³ª°¡ÀåóÀ½°Í
- else
- {
- SymTab = target->right_symbol;
- if(SymTab != NULL)
- SymTab->left_symbol = NULL;
- }
- temp = target->right_symbol; // ÀÓ½ÃÀúÀå
- // Free
- free(target->name);
- // Áö¿ï´ë»óÀÌÇÔ¼ö¶ó¸évalue¸¦free
- if(2 == type)
- free(target->str_func_value);
- free(target);
- target = temp; // ´ÙÀ½°ÍÀ»¼³Á¤
- }
- // typeÀ̸ÂÁö¾Ê´Ù¸é´ÙÀ½°ÍÀ»º»´Ù.
- else
- {
- target = target->right_symbol; // ´ÙÀ½°ÍÀ»¼³Á¤
- }
- }
- }
- // µð¹ö±×¸¦À§ÇØsymbol table Ãâ·ÂÇÏ´ÂÇÔ¼ö.
- void Symbol_Print_All(void)
- {
- SymbolTable* target = SymTab; // Çϳª¾¿»èÁ¦¸¦À§Çغ¯¼ö¼³Á¤.
- // ³¡±îÁö°Ë»ö
- while(NULL != target)
- {
- printf("name : %s\ttype : %d\n", target->name, target->type);
- target = target->right_symbol; // ´ÙÀ½°ÍÀ»¼³Á¤
- }
- }
- // Parsing function
- /*
- ** main parsing function
- */
- void parse(char *buf, double *result)
- {
- parse_parm pp;
- pp.buf = buf;
- pp.length = strlen(buf);
- pp.pos = 0;
- *result = 0;
- yylex_init(&pp.yyscanner);
- yyset_extra(&pp, pp.yyscanner);
- yyparse(&pp, pp.yyscanner);
- *result = pp.result;
- yylex_destroy(pp.yyscanner);
- }
"in Lesson" 카테고리의 다른 글
- 2009년 2학기 인공지능 - Report 02 (0)2009/10/26
- Minimax algorithm와 Alpha-beta pruning (2)2009/10/26
- 2009년 2학기 컴퓨터공학세미나 - 소감문 04 (0)2009/10/26
- 2009년 2학기 프로그래밍 언어론 - Report 01 (0)2009/10/18
- 2008년 1학기 심리학 입문 - 시험 대비 문서 (4)2009/10/13
- 2009년 2학기 컴퓨터공학세미나 - 소감문 03 (0)2009/10/11
- 2009년 2학기 문제해결기법 - Report 02 (0)2009/10/11
글에 잘못된 점, 다른 점, 부족한 점이 있다면 지적해주세요.
댓글, 트랙백, 메일 모두 고맙습니다.





README.pdf

댓글을 달아 주세요