Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

TXT

Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 6

%option noyywrap

%{
#include <cool-parse.h>
#include <stringtab.h>
#include <utilities.h>
#include <iostream>

/* The compiler assumes these identifiers. */


#define yylval cool_yylval
#define yylex cool_yylex

/* Max size of string constants */


#define MAX_STR_CONST 1025
#define YY_NO_UNPUT /* keep g++ happy */

extern FILE *fin; /* we read from this file */

/* define YY_INPUT so we read from the FILE fin:


* This change makes it possible to use this scanner in
* the Cool compiler.
*/
#undef YY_INPUT
#define YY_INPUT(buf,result,max_size) \
if ( (result = fread( (char*)buf, sizeof(char), max_size, fin)) < 0) \
YY_FATAL_ERROR( "read() in flex scanner failed");

char string_buf[MAX_STR_CONST]; /* to assemble string constants */


char *string_buf_ptr;

extern int curr_lineno;


extern int verbose_flag;

extern YYSTYPE cool_yylval;

int comment_counter=0;
bool open_comment=false;

bool string_too_long_check();
void check_nested_comment(int);

%}

DARROW =>
NEWLINE \n
WHITESPACE " "|"\f"|"\r"|"\t"|"\v"
DASHCOMM "--"
COMMENT_START "(*"
COMMENT_END "*)"
STRINGOC \"
NULL_CHARACTER \0
TYPEID [A-Z]({DIGIT}|{LETTER})*
OBJECTID [a-z]({DIGIT}|{LETTER})*
LETTER [a-zA-Z_]
DIGIT [0-9]
VALID_CHARACTERS
"."|":"|","|";"|"+"|"-"|"*"|"/"|"<"|"="|"("|")"|"{"|"}"|"@"|"~"
INVALID_CHARACTERS "`"|"!"|"#"|"$"|"%"|"^"|"&"|"_"|[\\]|">"|"?"|.|\001|\002|\
003|\004
NON_ESCAPE_CHARACTERS \\[^ntbf]

%x COMMENT
%x DASHCOMMENT
%x STRING

%%

<INITIAL>{
{DARROW} { return (DARROW); }

{COMMENT_START} {
comment_counter++;
open_comment=true;
BEGIN COMMENT;
}
{DASHCOMM} {

BEGIN DASHCOMMENT;
}

{COMMENT_END} {
cool_yylval.error_msg = "Unmatched *)";
return ERROR;
}
{STRINGOC} {
BEGIN STRING;
string_buf_ptr = string_buf;
}

<STRING>{
{STRINGOC} {
BEGIN INITIAL;
if(string_too_long_check())
{
BEGIN INITIAL;
cool_yylval.error_msg = "String constant too long";
return (ERROR);
}
*string_buf_ptr = '\0';

cool_yylval.symbol = stringtable.add_string(string_buf);
return(STR_CONST);
}

<<EOF>> {
cool_yylval.error_msg = "EOF in string constant";
BEGIN INITIAL;
return ERROR;
}

{NEWLINE} {
curr_lineno++;
cool_yylval.error_msg = "Unterminated string constant";
BEGIN INITIAL;
return ERROR;
}
{NULL_CHARACTER} {
cool_yylval.error_msg = "String contains null character";
return ERROR;
}

{NON_ESCAPE_CHARACTERS} {
if (string_too_long_check()) {
BEGIN INITIAL;
cool_yylval.error_msg = "String constant too long";
return (ERROR);
}
*string_buf_ptr++ = yytext[1];
}
\\. {
if (string_too_long_check()) {
BEGIN INITIAL;
cool_yylval.error_msg = "String constant too long";
return (ERROR);
}
switch(yytext[1]) {
case 'n':
*string_buf_ptr++ = '\n';
curr_lineno++;
break;
case 'b':
*string_buf_ptr++ = '\b';
break;
case 't':
*string_buf_ptr++ = '\t';
break;
case 'f':
*string_buf_ptr++ = '\f';
break;
default:
*string_buf_ptr = yytext[1];
string_buf_ptr++;
}
}

. {
if (string_too_long_check()) {
BEGIN INITIAL;
cool_yylval.error_msg = "String constant too long";
return (ERROR);
}
*string_buf_ptr++ = *yytext;
}

<DASHCOMMENT>{
{NEWLINE} {
curr_lineno++;
BEGIN INITIAL;
}
. {}
}

<COMMENT>{
{COMMENT_END} {
comment_counter--;
check_nested_comment(comment_counter);

{COMMENT_START} {

comment_counter++;
open_comment=true;
BEGIN COMMENT;

{NEWLINE} {
curr_lineno++;

<<EOF>> {

cool_yylval.error_msg = "EOF in comment";


BEGIN INITIAL;
return ERROR;
}

. {}
}

{NEWLINE} {curr_lineno++;}
{WHITESPACE} {}

[t][rR][uU][eE] {
cool_yylval.boolean = 1;
return(BOOL_CONST);
}
[f][aA][lL][sS][eE] {
cool_yylval.boolean = 0;
return(BOOL_CONST);
}
[T][rR][uU][eE] {
cool_yylval.symbol = stringtable.add_string(yytext);
return(TYPEID);
}

[F][aA][lL][sS][eE] {
cool_yylval.symbol = stringtable.add_string(yytext);
return(TYPEID);
}

{DIGIT}+ {
cool_yylval.symbol = inttable.add_string(yytext);
return(INT_CONST);
}

(?i:else) { return(ELSE);}
(?i:fi) {return(FI);}
(?i:if) {return(IF);}
(?i:in) {return(IN);}
(?i:inherits) {return(INHERITS);}
(?i:let) {return(LET);}
(?i:loop) {return(LOOP);}
(?i:pool) {return(POOL);}
(?i:then) {return(THEN);}
(?i:while) {return(WHILE);}
(?i:case) {return(CASE);}
(?i:esac) {return(ESAC);}
(?i:of) {return(OF);}
(?i:new) {return(NEW);}
(?i:isvoid) {return(ISVOID);}
(?i:assign) {return(ASSIGN);}
(?i:not) {return(NOT);}
(?i:class) {return(CLASS);}

bool_const {return(BOOL_CONST);}
error {return(ERROR);}

{OBJECTID} {
cool_yylval.symbol = stringtable.add_string(yytext);
return(OBJECTID);
}

{TYPEID} {
cool_yylval.symbol = stringtable.add_string(yytext);
return(TYPEID);
}

{VALID_CHARACTERS} { return(atoi)(yytext); }

{INVALID_CHARACTERS} {
cool_yylval.error_msg = yytext;
return ERROR;
}

%%

bool string_too_long_check(){

int num = (string_buf_ptr-string_buf)+1;


return(num > MAX_STR_CONST);
}

void check_nested_comment(int counter){

if(counter>0) BEGIN COMMENT;


else BEGIN INITIAL;
}

You might also like