/* SI 413 Fall 2021
* Lab 7
* This is a scanner specification for the SPL programming language.
* The semantic values are either leaves in the AST or operator codes.
*/
%{
#include <iostream>
#include <cstdlib>
using namespace std;
#include "value.hpp"
#include "ast.hpp"
#include "spl.tab.hpp"
// Called if there is a scanner error
void scanerror() {
if (! error) {
errout << "Unrecognized token starting with " << yytext << endl;
error = true;
}
}
// Returns the type of comparison operator that we are seeing.
Oper getCompOp(const char* text) {
switch(text[0]) {
case '=': return EQ;
case '!': return NE;
case '>': return (text[1] == '=' ? GE : GT);
case '<': return (text[1] == '=' ? LE : LT);
default: exit(8); // never reached
}
}
// Strips leading and trailing quote marks from the given C string
char* quotestrip(char* str) {
char* toret = str;
while (toret[0] == '"') ++toret;
for (int i=0; toret[i] != '\0'; ++i) {
if (toret[i] == '"') toret[i] = '\0';
}
return toret;
}
%}
%option noyywrap
%option nounput
%%
[0-9]+ {yylval.exp = new Num(atoi(yytext)); return NUM;}
true|false {yylval.exp = new BoolExp(yytext[0] == 't'); return BOOL;}
[+-] {yylval.op = (yytext[0] == '+' ? ADD : SUB); return OPA;}
[*/] {yylval.op = (yytext[0] == '*' ? MUL : DIV); return OPM;}
and|or {yylval.op = (yytext[0] == 'a' ? AND : OR); return BOP;}
not {yylval.op = NOT; return NOTTOK;}
":=" {return ASN;}
"@" {return FUNARG;}
"(" {return LP;}
")" {return RP;}
"{" {return LC;}
"}" {return RC;}
";" {return STOP;}
[><=]|([><!]=) {yylval.op = getCompOp(yytext); return COMP;}
if {return IF;}
ifelse {return IFELSE;}
while {return WHILE;}
read {return READ;}
write {return WRITE;}
lambda {return LAMBDA;}
new {return NEW;}
[a-zA-Z0-9_]+ {yylval.id = new Id(yytext); return ID;}
<<EOF>> { return 0; }
[ \t\n]+ { }
"#".* { }
. { scanerror(); return -1; }
%%