Untitled
unknown
plain_text
2 years ago
4.1 kB
12
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