Untitled

 avatar
unknown
plain_text
a year ago
5.4 kB
5
Indexable
/*
 *  The scanner definition for COOL.
 */

/*
 *  Stuff enclosed in %{ %} in the first section is copied verbatim to the
 *  output, so headers and global definitions are placed here to be visible
 * to the code in the file.  Don't remove anything that was here initially
 */

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

/* 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 */
/*
   The two statements below are here just so this program will compile.
   You may need to change or remove them on your final code.
*/
#define yywrap() 1
#define YY_SKIP_YYWRAP

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;

/*
 *  Add Your own definitions here
 */

int commentLevel = 0;
std::string readString = "";
int readNullToken = 0;

%}

DARROW          =>
LE              <=
ASSIGN          <-

WHITESPACE      (" "|"\t"|"\r"|"\f"|"\v")
DIGIT           [0-9]

OPERATORS       ("+"|"-"|"*"|"/")
PUNCTUATION     (":"|";"|"."|",")
SYMBOLS         ("("|")"|"{"|"}"|"@"|"~"|"<"|"=")
INVALIDS        ("!"|"#"|"$"|"%"|"^"|"&"|"_"|">"|"?"|"`"|"["|"]"|"|"|"\\")

IDSUFFIX        [0-9a-zA-Z_]
TYPEID          [A-Z]{IDSUFFIX}*
OBJECTID        [a-z]{IDSUFFIX}*

%START MULTILINE_COMMENT
%START SINGLELINE_COMMENT
%START STRING

%%

<INITIAL,MULTILINE_COMMENT,SINGLELINE_COMMENT>"(*" {
  commentLevel += 1;
  BEGIN MULTILINE_COMMENT;
}

<MULTILINE_COMMENT>[^\n(*]* { }

<MULTILINE_COMMENT>[()*] { }

<MULTILINE_COMMENT>"*)" {
  commentLevel -= 1;
  if (commentLevel == 0) BEGIN INITIAL;
}

<MULTILINE_COMMENT><<EOF>> {
  BEGIN INITIAL;

  yylval.error_msg = (char*)"EOF in comment";
  return (ERROR);
}

"*)" {
  yylval.error_msg = (char*)"Unmatched *)";
  return (ERROR);
}

<INITIAL>"--" {
  BEGIN SINGLELINE_COMMENT;
}

<SINGLELINE_COMMENT>[^\n]* { }

<SINGLELINE_COMMENT>\n {
    curr_lineno += 1;
    BEGIN INITIAL;
}

<INITIAL>\" {
  readString = "";
  readNullToken = 0;

  BEGIN STRING;
}

<STRING>[^\n\0"\\]* {
  readString += yytext;
}

<STRING>\\(.|\n) {
  switch(yytext[1]) {
    case '\n':
      curr_lineno += 1;
      readString += '\n';
      break; 
    case 'n':
      readString += '\n';
      break; 
    case 't':
      readString += '\t';
      break; 
    case 'f':
      readString += '\f';
      break; 
    case 'b':
      readString += '\b';
      break; 
    case '\0': 
      readNullToken = 1;
      break;
    default:
      readString += yytext[1];
      break;
  }
}

<STRING>\n {
  BEGIN INITIAL;

  curr_lineno += 1;

  yylval.error_msg = (char*)"Unterminated string constant";
  return (ERROR);
}

<STRING>\0 {
  readNullToken = 1;
}

<STRING>\" {
  BEGIN INITIAL;

  if(readNullToken == 1) {
    yylval.error_msg = (char*)"String contains null character";
    return (ERROR);
  }

  if(readString.length() >= MAX_STR_CONST) {
    yylval.error_msg = (char*)"String constant too long";
    return (ERROR);
  }

  yylval.symbol = stringtable.add_string((char *) readString.c_str());
  return (STR_CONST);
}

<STRING><<EOF>> {
  BEGIN INITIAL;

  yylval.error_msg = (char*)"EOF in string constant";
  return (ERROR);
}

"t"[rR][uU][eE] {
  yylval.boolean = 1;
  return (BOOL_CONST);
}
"f"[aA][lL][sS][eE] {
  yylval.boolean = 0;
  return (BOOL_CONST);
}
[cC][lL][aA][sS][sS]	            { return (CLASS); }
[eE][lL][sS][eE] 			            { return (ELSE); }
[fF][iI]                          { return (FI); }
[iI][fF]                          { return (IF); }
[Ii][Nn]                          { return (IN); }
[iI][nN][hH][eE][rR][iI][tT][sS]  { return (INHERITS); } 
[iI][sS][vV][oO][iI][dD]	        { return (ISVOID); } 
[lL][eE][tT]                      { return (LET); }
[lL][oO][oO][pP]	                { return (LOOP); }
[pP][oO][oO][lL]	                { return (POOL); }
[tT][hH][eE][nN]	                { return (THEN); }
[wW][hH][iI][lL][eE]	            { return (WHILE); }
[cC][aA][sS][eE]	                { return (CASE); }
[eE][sS][aA][cC]	                { return (ESAC); }
[nN][eE][wW]	                    { return (NEW); }
[oO][fF]	                        { return (OF); }
[nN][oO][tT]	                    { return (NOT); }

"=>"            { return (DARROW); }
"<-"            { return (ASSIGN); }
"<="            { return (LE); }

{SYMBOLS}       { return yytext[0]; }

{PUNCTUATION}   { return yytext[0]; }

{OPERATORS}     { return yytext[0]; }


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

{TYPEID}        { yylval.symbol = idtable.add_string(yytext); return (TYPEID); }
{OBJECTID}      { yylval.symbol = idtable.add_string(yytext); return (OBJECTID); }

\n              { curr_lineno += 1; }
{WHITESPACE}+   {  }

{INVALIDS}      { yylval.error_msg = yytext; return (ERROR); }

.               { yylval.error_msg = yytext; return (ERROR); }

%%
Editor is loading...
Leave a Comment