Untitled

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

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

/* 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 nested_comments = 0;
std::string readString = "";
int readNullToken = 0;

%}

SINGLE_TOKENS [{|}|(|)|:|;|@|,|.|+|\-|*|/|=|<|~]
QUOTES \"

/* 
 *  The multiple-character operators. 
 */
DARROW     =>
ASSIGN     <-
LE         <=   

DIGIT      [0-9]
OBJID      [a-z][a-zA-Z0-9_]*
TYPEID     [A-Z][a-zA-Z0-9_]*

%x STR   
%x COMMENT
%x TREAT_STR_ERROR
%x DASH_COMMENT
%x MULTILINE_COMMENT
%x SINGLELINE_COMMENT

%%

/* Common Rules */
[ \t\r\f\v]+ {/*skip whitespace*/}
\n          { curr_lineno++; }
{DIGIT}+ {
  cool_yylval.symbol = idtable.add_string(yytext);
  return (INT_CONST);
}
{SINGLE_TOKENS} { return int(yytext[0]); }

/* Common Keywords */
"t"[rR][uU][eE] {
  cool_yylval.boolean = 1;
  return (BOOL_CONST);
}
"f"[aA][lL][sS][eE] {
  cool_yylval.boolean = 0;
  return (BOOL_CONST);
}
{CLASS}	{ return (CLASS); }
{ELSE}	{ return (ELSE); }
{FI}	{ return (FI); }
{IF}	{ return (IF); }
{IN}	{ return (IN); }
{INHERITS}	{ return (INHERITS); } 
{ISVOID}	{ return (ISVOID); } 
{LET}	{ return (LET); }
{LOOP}	{ return (LOOP); }
{POOL}	{ return (POOL); }
{THEN}	{ return (THEN); }
{WHILE}	{ return (WHILE); }
{CASE}	{ return (CASE); }
{ESAC}	{ return (ESAC); }
{NEW}	{ return (NEW); }
{OF}	{ return (OF); }
{NOT}	{ return (NOT); }

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

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

/* Comments */
"--" { BEGIN(SINGLELINE_COMMENT); }
"(*" { BEGIN(MULTILINE_COMMENT); }

<MULTILINE_COMMENT>{
  [^\n(*]* { }
  [()*] { }
  "*)" {
    nested_comments--;
    if (nested_comments == 0){
      BEGIN(INITIAL);
    }
  }
  <<EOF>> {
    yylval.error_msg = (char*)"EOF in comment";
    BEGIN(INITIAL);
    return (ERROR);
  }
}

<SINGLELINE_COMMENT>{
  [^\n]* { }
  \n {
    curr_lineno += 1;
    BEGIN(INITIAL);
  }
}

/* Strings */
<INITIAL>\" { readString = ""; readNullToken = 0; BEGIN(STR); }
<STR>{
  [^\n\0"\\]* {
    readString += yytext;
  }
  \\(.|\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;
    }
  }
  \n {
    BEGIN(INITIAL);
    curr_lineno += 1;
    yylval.error_msg = (char*)"Unterminated string constant";
    return (ERROR);
  }
  \0 {
    readNullToken = 1;
  }
  \" {
    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);
    }
    cool_yylval.symbol = stringtable.add_string((char *) readString.c_str());
    return (STR_CONST);
  }
  <<EOF>> {
    BEGIN(INITIAL);
    yylval.error_msg = (char*)"EOF in string constant";
    return (ERROR);
  }
}

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

%%

Editor is loading...
Leave a Comment