Untitled

 avatar
user_2381398
plain_text
2 years ago
3.9 kB
2
Indexable
%{
#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);
}