main.c
main.c #include <stdio.h> #include <stdlib.h> #include "lex.h"
extern FILE *yyin; /* input stream */
extern int yylval, /* integer value of TK_NUM */ yylen; /* length of TK_ID string */
extern char *yytext; /* point to TK_ID string */
main(argc, argv) register int argc; register char *argv[]; { int n, i; char *c;
if (argc != 2) { fprintf(stderr, "usage: scan <input>\n"); exit(1) ; }
if ((yyin = fopen(argv[1], "r")) == NULL) { fprintf(stderr, "can't open %s\n", argv[1]); exit(1) ; }
n = yylex(); while (n) { switch(n) { case TK_ID: printf("%s", "TK_ID: "); c = yytext; for (i=0; i<yylen; i++) printf("%c", *c++); printf("\n"); break; case TK_NUM: printf("%s", "TK_NUM: "); printf("%d\n", yylval); break; case TK_IF: printf("%s\n", "TK_IF"); break; case TK_ELSE: printf("%s\n", "TK_ELSE"); break; case TK_ASSIGN: printf("%s\n", "TK_ASSIGN"); break; case TK_EQ: printf("%s\n", "TK_EQ"); break; case TK_NE: printf("%s\n", "TK_NE"); break; case TK_GT: printf("%s\n", "TK_GT"); break; case TK_GE: printf("%s\n", "TK_GE"); break; case TK_LT: printf("%s\n", "TK_LT"); break; case TK_LE: printf("%s\n", "TK_LE"); break; case TK_LPAR: printf("%s\n", "TK_LPAR"); break; case TK_RPAR: printf("%s\n", "TK_RPAR"); break; case TK_SCOLON: printf("%s\n", "TK_SCOLON"); break; } n = yylex(); } printf("%s\n", "TK_EOF");
fclose(yyin); } |
lex.h
lex.h #define TK_ID 256 #define TK_NUM 257 #define TK_IF 258 #define TK_ELSE 259 #define TK_ASSIGN 260 #define TK_EQ 261 #define TK_NE 262 #define TK_GT 263 #define TK_GE 264 #define TK_LT 265 #define TK_LE 266 #define TK_LPAR 267 #define TK_RPAR 268 #define TK_SCOLON 269 #define TK_EOF 270 |
lex.l
lex.l %{ #include <stdio.h> #include <string.h> #include "lex.h"
static int linenumber = 1, columnnumber = 0; static int count(); static int comment(); static int invalid_char();
char err_msg[30]; /* error message buffer */ int yylval, yylen; char *yytext; //static unsigned char *forwward=yytext; %}
delim [ \t\n] ws {delim}+ letter [A-Za-z] digit [0-9] id {letter}({letter}|{digit})* number {digit}+(\.{digit}+)?(E[+\-]?{digit}+)?
%%
{ws} {count();} if {count(); return (TK_IF);} else {count(); return (TK_ELSE);} {id} {yylen = strlen(yytext); count(); return (TK_ID);} {number} {yylval = atoi(yytext); count(); return (TK_NUM);} "<" {count(); return (TK_GT);} "<=" {count(); return (TK_GE);} ">" {count(); return (TK_LT);} ">=" {count(); return (TK_LE);} "=" {count(); return (TK_ASSIGN);} "!=" {count(); return (TK_NE);} "==" {count(); return (TK_EQ);} "(" {count(); return (TK_LPAR);} ")" {count(); return (TK_RPAR);} ";" {count(); return (TK_SCOLON);} "/*" {count(); comment();} . {count(); invalid_char();}
%%
yywrap() { return(1); }
/* prints the current line, column error message */ void yyerror(msg) char *msg; { fprintf(stderr, "line:%3d, column:%3d %s\n", linenumber, columnnumber, msg); }
/* keep column numbers correct */ static int count() { int i;
for(i = 0; yytext[i] != '\0'; i++) if(yytext[i] == '\n') { linenumber++; columnnumber = 0; } else if(yytext[i] == '\t') columnnumber += 8 - (columnnumber%8); else columnnumber++; }
/* read remainder of comments */ static int comment() { char c;
c = input(); do { unput(c); while((c=input()) != '*') if (c =='\n'){ linenumber++; columnnumber = 0; } else if (c =='\t') columnnumber += 8 - (columnnumber%8); else columnnumber++; columnnumber++; /* count the closing '*' */ } while((c=input()) != '/'); columnnumber++; /* count the closing '/' */ }
static int invalid_char() { sprintf(err_msg, "invalid character: 0x%x", yytext[0]); yyerror(err_msg); }
|
'대학교 > 4.컴파일러' 카테고리의 다른 글
[02] lex.c (0) | 2019.04.14 |
---|---|
[01] wc (0) | 2019.03.20 |