Created
December 16, 2019 19:22
-
-
Save ghaiklor/f705d586bc13563b232256218a8a64b7 to your computer and use it in GitHub Desktop.
Flex specification for COOL language
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%{ | |
#include <cool-parse.h> | |
#include <stringtab.h> | |
#include <utilities.h> | |
#include <string.h> | |
#define yylval cool_yylval | |
#define yylex cool_yylex | |
#define MAX_STR_CONST 1025 | |
#define YY_NO_UNPUT /* keep g++ happy */ | |
extern FILE *fin; /* we read from this file */ | |
#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_depth = 0; | |
%} | |
%option yylineno | |
%x COMMENT | |
%x STRING | |
%x STRING_ERROR | |
NEWLINE \n | |
WHITESPACE [ \n\f\r\t\v] | |
ONELINE_COMMENT "--"(.*) | |
CLASS (?i:class) | |
ELSE (?i:else) | |
FI (?i:fi) | |
IF (?i:if) | |
IN (?i:in) | |
INHERITS (?i:inherits) | |
ISVOID (?i:isvoid) | |
LET (?i:let) | |
LOOP (?i:loop) | |
POOL (?i:pool) | |
THEN (?i:then) | |
WHILE (?i:while) | |
CASE (?i:case) | |
ESAC (?i:esac) | |
NEW (?i:new) | |
OF (?i:of) | |
NOT (?i:not) | |
FALSE "f"(?i:alse) | |
TRUE "t"(?i:rue) | |
DARROW => | |
ASSIGN <- | |
LE <= | |
INTEGER [0-9]+ | |
TYPE_ID [A-Z][a-zA-Z0-9_]* | |
OBJECT_ID [a-z][a-zA-Z0-9_]* | |
SYMBOLS [\(\)\{\}\=\<\~\@\/\*\-\+\:\;\.\,] | |
%% | |
<INITIAL>{ | |
"(*" { BEGIN(COMMENT); comment_depth++; } | |
"*)" { curr_lineno = yylineno; cool_yylval.error_msg = "Unmatched *)"; return (ERROR); } | |
"\"" { strcpy(string_buf, ""); BEGIN(STRING); } | |
} | |
<COMMENT>{ | |
<<EOF>> { curr_lineno = yylineno; cool_yylval.error_msg = "EOF in comment"; BEGIN(INITIAL); return (ERROR); } | |
"(*" { comment_depth++; } | |
"*)" { comment_depth--; if (comment_depth == 0) { BEGIN(INITIAL); } } | |
\n { curr_lineno = yylineno; } | |
. { curr_lineno = yylineno; } | |
} | |
<STRING>{ | |
\\\x00 { | |
curr_lineno = yylineno; | |
cool_yylval.error_msg = "String contains escaped null character."; | |
BEGIN(STRING_ERROR); | |
return (ERROR); | |
} | |
\\. { | |
int len = strlen(string_buf); | |
curr_lineno = yylineno; | |
if ((len + 1 + 1) > MAX_STR_CONST) { | |
cool_yylval.error_msg = "String constant too long"; | |
BEGIN(STRING_ERROR); | |
return (ERROR); | |
} | |
if (yytext[1] == 'b') { string_buf[len] = '\b'; } else | |
if (yytext[1] == 't') { string_buf[len] = '\t'; } else | |
if (yytext[1] == 'n') { string_buf[len] = '\n'; } else | |
if (yytext[1] == 'f') { string_buf[len] = '\f'; } else | |
{ string_buf[len] = yytext[1]; } | |
string_buf[len + 1] = '\0'; | |
} | |
\" { | |
curr_lineno = yylineno; | |
cool_yylval.symbol = stringtable.add_string(string_buf); | |
BEGIN(INITIAL); | |
return (STR_CONST); | |
} | |
\x00 { | |
curr_lineno = yylineno; | |
cool_yylval.error_msg = "String contains null character"; | |
BEGIN(STRING_ERROR); | |
return (ERROR); | |
} | |
\\\n { | |
int len = strlen(string_buf); | |
if ((len + 1 + 1) > MAX_STR_CONST) { | |
cool_yylval.error_msg = "String constant too long"; | |
BEGIN(STRING_ERROR); | |
return (ERROR); | |
} | |
string_buf[len] = '\n'; | |
string_buf[len + 1] = '\0'; | |
curr_lineno = yylineno; | |
} | |
\n { | |
curr_lineno = yylineno; | |
cool_yylval.error_msg = "Unterminated string constant"; | |
BEGIN(INITIAL); | |
return (ERROR); | |
} | |
<<EOF>> { | |
curr_lineno = yylineno; | |
cool_yylval.error_msg = "EOF in string constant"; | |
BEGIN(INITIAL); | |
return (ERROR); | |
} | |
[^\\\"\x00\n]+ { | |
curr_lineno = yylineno; | |
if ((strlen(string_buf) + strlen(yytext) + 1) > MAX_STR_CONST) { | |
cool_yylval.error_msg = "String constant too long"; | |
BEGIN(STRING_ERROR); | |
return (ERROR); | |
} | |
strcat(string_buf, yytext); | |
} | |
} | |
<STRING_ERROR>{ | |
([\"]|[^\\]\n) { curr_lineno = yylineno; BEGIN(INITIAL); } | |
. { /* DO NOTHING */ } | |
} | |
{NEWLINE} { } | |
{WHITESPACE} { } | |
{ONELINE_COMMENT} { curr_lineno = yylineno; } | |
{CLASS} { curr_lineno = yylineno; return (CLASS); } | |
{ELSE} { curr_lineno = yylineno; return (ELSE); } | |
{FI} { curr_lineno = yylineno; return (FI); } | |
{IF} { curr_lineno = yylineno; return (IF); } | |
{IN} { curr_lineno = yylineno; return (IN); } | |
{INHERITS} { curr_lineno = yylineno; return (INHERITS); } | |
{ISVOID} { curr_lineno = yylineno; return (ISVOID); } | |
{LET} { curr_lineno = yylineno; return (LET); } | |
{LOOP} { curr_lineno = yylineno; return (LOOP); } | |
{POOL} { curr_lineno = yylineno; return (POOL); } | |
{THEN} { curr_lineno = yylineno; return (THEN); } | |
{WHILE} { curr_lineno = yylineno; return (WHILE); } | |
{CASE} { curr_lineno = yylineno; return (CASE); } | |
{ESAC} { curr_lineno = yylineno; return (ESAC); } | |
{NEW} { curr_lineno = yylineno; return (NEW); } | |
{OF} { curr_lineno = yylineno; return (OF); } | |
{NOT} { curr_lineno = yylineno; return (NOT); } | |
{DARROW} { curr_lineno = yylineno; return (DARROW); } | |
{ASSIGN} { curr_lineno = yylineno; return (ASSIGN); } | |
{LE} { curr_lineno = yylineno; return (LE); } | |
{FALSE} { | |
cool_yylval.boolean = false; | |
curr_lineno = yylineno; | |
return (BOOL_CONST); | |
} | |
{TRUE} { | |
cool_yylval.boolean = true; | |
curr_lineno = yylineno; | |
return (BOOL_CONST); | |
} | |
{INTEGER} { | |
cool_yylval.symbol = inttable.add_string(yytext); | |
curr_lineno = yylineno; | |
return (INT_CONST); | |
} | |
{TYPE_ID} { | |
cool_yylval.symbol = idtable.add_string(yytext); | |
curr_lineno = yylineno; | |
return (TYPEID); | |
} | |
{OBJECT_ID} { | |
cool_yylval.symbol = idtable.add_string(yytext); | |
curr_lineno = yylineno; | |
return (OBJECTID); | |
} | |
{SYMBOLS} { | |
curr_lineno = yylineno; | |
return (yytext[0]); | |
} | |
. { | |
curr_lineno = yylineno; | |
cool_yylval.error_msg = yytext; | |
return (ERROR); | |
} | |
%% |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment