TXT
TXT
TXT
%{
#include <cool-parse.h>
#include <stringtab.h>
#include <utilities.h>
#include <iostream>
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>> {
. {}
}
{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(){