%{ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Μιχάλης Παπακυριάκου mpapakyr@softlab.ece.ntua.gr * * * * Θοδωρής Τσόκος tsokos@softlab.ece.ntua.gr * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Εισαγωγή στους Μεταγλωττιστές * * Εργαστήριο Τεχνολογίας Λογισμικού * * * * Θέμα: `Κατασκευή Μεταγλωττιστή γλώσσας Calvin` * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * File Name: yylex.l * * Version: 1.0 Final * * Description: Flex source code * * Date: 23/10/2003 1:12μμ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include "grammar.tab.h" #define max_length 255 #define TK_EOF 0 #define FILE_ERROR 1 #define TK_ERROR 2 typedef struct Stack_tag { int line_no; FILE* fp; YY_BUFFER_STATE buf; struct Stack_tag *next; } Stack; typedef struct file_list_tag { char name[max_length]; struct file_list_tag *next; } file_list; char write_file[max_length]; int line_count=1; int no_files=0; int depth = 0; Stack *Top = NULL; file_list *head=NULL; void user_output(int value,char* file); void push(FILE*,int); int pop(FILE** ,int*); void insert(char[]); int check(char[]); void write_tokens(int value,FILE* output); char include_name[max_length]; %} WHITE_CHAR [ \t\r] NEW_LINE [\n] DIGIT [0-9] LETTER [A-Za-z] SIGN [\+\-] QUOTE [\'] D_QUOTE [\"] UNDERSCORE [_] MORE_CHARS (\\[n\"\'0t\\]) STRING [^\n\"] %x COMMENT INCLUDE %% "char" {return TK_WORD_CHAR;} "else" {return TK_WORD_ELSE;} "if" {return TK_WORD_IF;} "integer" {return TK_WORD_INTEGER;} "main" {return TK_WORD_MAIN;} "return" {return TK_WORD_RETURN;} "void" {return TK_WORD_VOID;} "while" {return TK_WORD_WHILE;} "[" {return TK_AGK_OPEN;} "]" {return TK_AGK_CLOSE;} "(" {return TK_PAR_OPEN;} ")" {return TK_PAR_CLOSE;} "{" {return TK_AGKISTRO_OPEN;} "}" {return TK_AGKISTRO_CLOSE;} "," {return TK_COMMA;} ";" {return TK_EROTIM;} "=" {return TK_ASSIGN;} "&" {return TK_AMPERSAND;} "+" {return TK_OP_PLUS;} "-" {return TK_OP_MINUS;} "*" {return TK_OP_MULT;} "/" {return TK_OP_DIV;} "%" {return TK_OP_MOD;} "==" {return TK_OP_EQUAL;} "!=" {return TK_OP_NOTEQUAL;} ">=" {return TK_OP_GREATEREQ;} "<=" {return TK_OP_LESSEQ;} ">" {return TK_OP_GREATER;} "<" {return TK_OP_LESS;} "||" {return TK_OP_OR;} "&&" {return TK_OP_AND;} "!" {return TK_OP_NOT;} "/*" {BEGIN(COMMENT);} "*/" {BEGIN(INITIAL);} {NEW_LINE} {line_count++;} <> {error("EOF encoutered inside a comment");} "*" {;} [^*\n] {;} "//"[^\n]* {;} ^"#include"{WHITE_CHAR}*"\"" {BEGIN(INCLUDE);} "\"" { FILE* input; if((input=fopen(include_name,"r"))==NULL) { error("File could not be included: %s", include_name); insert(include_name); BEGIN(INITIAL); } else if(check(include_name)) ; // do nothing, already included else { depth++; push(yyin,line_count); yyin = input; yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE)); line_count=1; insert(include_name); // yyrestart(input); BEGIN(INITIAL); } } {NEW_LINE} { printf("\nYour file was not included. Check the syntax. Possible grammar errors\n"); return FILE_ERROR; } [^(\n\")]+ { strcpy(include_name, yytext); } <> {error("EOF encoutered unexpectedly");} {WHITE_CHAR}+ {/* nothing */} ({LETTER}|{UNDERSCORE})({LETTER}|{DIGIT}|{UNDERSCORE})* { strcpy(yylval.name, yytext); return TK_IDENT; } {DIGIT}+ { yylval.integer = atoi(yytext); return TK_INT; } {DIGIT}+({LETTER}|{UNDERSCORE}) {error("Non digits in integer constant");} {QUOTE}({STRING}|{MORE_CHARS}){QUOTE} { if(yytext[1] == '\\') switch(yytext[2]) { case 'n': yylval.ch = 10; break; case 't': yylval.ch = 9; break; case '\"': yylval.ch = 34; break; case '\'': yylval.ch = 96; break; case '0': yylval.ch = 0; break; case '\\': yylval.ch = 92; break; } else yylval.ch = yytext[1]; return TK_CHAR; } {D_QUOTE}{STRING}+{D_QUOTE} { yylval.s = (char *)malloc(strlen(yytext) +1); strcpy(yylval.s, yytext); return TK_STRING; } {NEW_LINE} {line_count++;} . {error("Unkown character :%s", yytext);} %% int yywrap () { FILE * input; if (pop(&input, &line_count)) return 1; else { yyin = input; depth--; return 0; } } char file[] = ""; /* fix this !!! */ FILE* output; /* this was in main */ int main2(int argc,char **argv){ int token; char *filename="stdin"; if(argc>1) { filename=argv[1]; if ((yyin=fopen(argv[1],"r"))<0) { printf("%s: File Not Found",filename); exit(1); } else { strcpy(write_file,filename); strcat(write_file,".tokens"); } } else { yyin=stdin; strcpy(write_file,"out.tokens"); } output=fopen(write_file,"w"); while( (token=yylex()) != TK_EOF ) write_tokens(token,output); if (yyin!=stdin) fclose(yyin); return 0; } void push(FILE *a,int b) { Stack * new = (Stack *) malloc(sizeof(Stack)); if (new == NULL) { fprintf(stderr, "Out of memory\n"); exit(1); } new->fp=a; new->line_no=b; new->next=Top; new->buf=YY_CURRENT_BUFFER; Top=new; } int pop(FILE **a,int *b) { if(Top==NULL) return 1; else { *a=Top->fp; *b=Top->line_no; yy_delete_buffer(YY_CURRENT_BUFFER); fclose(yyin); yy_switch_to_buffer(Top->buf); Top=Top->next; return 0; } } void insert(char file[]) { file_list *new = (file_list *) malloc(sizeof(file_list)); if (new == NULL) { fprintf(stderr, "Out of memory\n"); exit(1); } strcpy(new->name,file); new->next=head; head=new; } int check(char file[]) { file_list *temp; temp=head; if(head==NULL) return 0; else if(!strcmp(file,head->name)) return 1; else while(temp->next!=NULL) { if(!strcmp(temp->next->name,file)) return 1; temp=temp->next; } return 0; } void write_tokens(int value,FILE* output){ switch (value) { case TK_IDENT: fprintf(output,"%s :[%d] IDENTIFIER: %s\n",file,line_count,yytext); break; case TK_INT: fprintf(output,"%s :[%d] INTEGER : %s\n",file,line_count,yytext); break; case TK_CHAR: fprintf(output,"%s :[%d] CHARACTER : %s\n",file,line_count,yytext); break; case TK_STRING: fprintf(output,"%s :[%d] STRING : %s\n",file,line_count,yytext); break; case TK_ERROR: fprintf(output,"%s :[%d] ERROR : %s\n",file,line_count,yytext); break; case FILE_ERROR: fprintf(output,"%s :[%d] FILE_ERROR: %s\n",file,line_count,yytext); break; default: fprintf(output,"%s :[%d] OTHER : %s\n",file,line_count,yytext); break; } }