%{
#include <iostream>
#include <map>
#include <vector>
using namespace std;
#define LIST strcat(buf,yytext)
#define token(t) {LIST; printf("<%s>\n",#t);}
#define tokenInteger(t,i) {LIST; printf("<%s:%d>\n",t,i);}
#define tokenString(t,s) {LIST; printf("<%s:%s>\n",t,s);}
#define MAX_LINE_LENG 256
int linenum = 0;
bool Opt_L = true;
char buf[MAX_LINE_LENG];
char strbuf[MAX_LINE_LENG];
class SymbolTable{
private:
vector<string> i_symbol;
map<string,int> symbol_i;
int index;
public:
SymbolTable();
int lookup(string s);
int insert(string s);
int dump();
};
SymbolTable *stb;
%}
whitespace [ \t]+
digit [0-9]
letter [a-zA-Z]
identifier {letter}({digit}|{letter})*
integer {digit}+
/* states */
%x COMMENT
%x STR
%%
"." {token('.');}
"," {token(',');}
":" {token(':');}
";" {token(';');}
"(" {token('(');}
")" {token(')');}
"[" {token('[');}
"]" {token(']');}
"{" {token('{');}
"}" {token('}');}
"+" {token('+');}
"-" {token('-');}
"*" {token('*');}
"/" {token('/');}
"mod" {token('mod');}
":=" {token(':=');}
"<" {token('<');}
"<=" {token('<=');}
">" {token('>');}
">=" {token('>=');}
"==" {token('==');}
"=" {token('=');}
"not=" {token('not=');}
"and" {token('and');}
"or" {token('or');}
"not" {token('not');}
"array" {token('ARRAY');}
"begin" {token('BEGIN');}
"bool" {token(BOOL);}
"char" {token('CHAR');}
"const" {token(CONST);}
"decreasing" {token('DECREASING');}
"default" {token(DEFAULT);}
"do" {token('DO');}
"else" {token(ELSE);}
"end" {token('END');}
"exit" {token('EXIT');}
"false" {token('FALSE');}
"for" {token(FOR);}
"function" {token(FUNCTION);}
"get" {token(GET);}
"if" {token(IF);}
"int" {token(INT);}
"loop" {token('LOOP');}
"of" {token('OF');}
"put" {token('PUT');}
"procedure" {token('PROCEDURE');}
"real" {token(REAL);}
"result" {token('RESULT');}
"return" {token(RETURN);}
"skip" {token('SKIP');}
"string" {token(STRING);}
"then" {token('THEN');}
"true" {token('TRUE');}
"var" {token(VAR);}
"when" {token('WHEN');}
{identifier} {
tokenString("id",yytext);
stb->insert(yytext);
}
{integer} {
tokenInteger("integer",atoi(yytext));
}
{integer}"."{integer}([Ee][+-]{integer})? {
tokenString("real",yytext);
}
"\"" {
LIST;
strbuf[0]='\0';
BEGIN STR;
}
<STR>"\"" {
char c = yyinput();
if(c != '"'){
strcat(buf,"\"");
printf("<%s: %s>\n", "string", strbuf);
unput(c);
BEGIN INITIAL;
}else{
strcat(buf,"\"\"");
strcat(strbuf,"\"");
}
}
<STR>[^"\n]* {
LIST;
strcat(strbuf,yytext);
}
<STR>"\n" {
printf("[ERROR] at line %d, double quote not closed\n", linenum);
exit(-1);
}
"//"[^\n]* {LIST;}
"/*" {
LIST;
BEGIN COMMENT;
}
<COMMENT>\n {
LIST;
printf("%d: %s", linenum++, buf);
buf[0] = '\0';
}
<COMMENT>. {
LIST;
}
<COMMENT>"*/" {
LIST;
BEGIN INITIAL;
}
"*/" {LIST;}
\n {
LIST;
if(Opt_L)
printf("%d: %s", linenum, buf);
linenum++;
buf[0] = '\0';
}
{whitespace} {LIST;}
. {
LIST;
printf("%d:%s\n", linenum+1, buf);
printf("bad character:'%s'\n",yytext);
exit(-1);
}
%%
SymbolTable::SymbolTable(){
index = 0;
}
int SymbolTable::lookup(string s){
if(symbol_i.find(s) != symbol_i.end()){
return symbol_i[s];
}else{
return -1; // not found
}
}
int SymbolTable::insert(string s){
if(symbol_i.find(s) != symbol_i.end()){
return -1; // find it in SymbolTable
}
i_symbol.push_back(s);
symbol_i[s] = index;
index++;
return index-1;
}
int SymbolTable::dump(){
for(int i=0;i<index;i++){
printf("%d : %s\n",i,i_symbol[i].c_str());
}
return i_symbol.size();
}
void create(){
stb = new SymbolTable();
}
int main(int argc, char *argv[]){
create();
yylex();
cout << "\n\nSymbol Table: \n";
stb->dump();
fflush(yyout);
exit(0);
}