Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
бАКАЛАВР_РАБОТА.docx
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
2.13 Mб
Скачать

В.3 Модуль семантического анализатора Файл symbolTable.H

#ifndef SYMBOLTABLE_H

#define SYMBOLTABLE_H

#include <exception/syntax_error.h>

#ifdef IS_UNIX

#include <tr1/unordered_map> /// WINDOWS

#else

#include <unordered_map>

#endif

namespace std{

using tr1::unordered_map;

}

namespace parser_LL1{

class ObjType;

using std::string;

typedef std::unordered_map<string,ObjType *> hashmap;

class SymbolTable{

private:

hashmap table;

public:

SymbolTable(){}

ObjType* lookup(const string& word){

hashmap::const_iterator i = table.find(word);

if( i != table.end() ) return i->second;

return 0;

}

ObjType* get(const string& word){

hashmap::const_iterator i = table.find(word);

if( i != table.end() ) return i->second;

else throw error::Parser_error("Identifier not found: " + word);

}

void add(const string& word,ObjType* x){

hashmap::const_iterator i = table.find(word);

if( i != table.end() ) throw error::Parser_error("Identifier already exists: " + word); // error

table.insert(std::make_pair(word,x));

}

};

}// parser_LL1

#endif // SYMBOLTABLE_H

Файл SymbolTableFactory.H

#ifndef SYMBOLTABLEFACTORY_H

#define SYMBOLTABLEFACTORY_H

#include "symbolTable.h"

#include "ast/ast.h"

#include "ast/objType.h"

#include <vector>

namespace parser_LL1{

class SymbolTableFactory{

private:

Program* program;

std::vector<std::pair<int,int>>* makeList(ListExpr* l){

std::vector<std::pair<int,int>>* i=new std::vector<std::pair<int,int>>;

while(l!=0){

Interval* curr=dynamic_cast<Interval*>(l->first());

if(!curr) break;

i->push_back(std::make_pair(curr->lvalue(),curr->rvalue()));

l=dynamic_cast<ListExpr*>(l->rest());

}

return i;

}

public:

SymbolTableFactory(Node* pr){

this->program=dynamic_cast<Program*>(pr);

if(!program)

throw error::System_error("incorrect ast building parser - SymbolTableFactory");

}

SymbolTable* build(){

SymbolTable* t=new SymbolTable();

Seq* d=program->declarations();

// declarations - macro , array , const , count types

while(d!= 0){

Stmt* current=d->first();

if(current==0) break;

if(typeid(*current)== typeid(DeclMacro)){

DeclMacro* m=dynamic_cast<DeclMacro*>(current);

if(m->parametr() == 0){

t->add(m->identifier()->value(),new MacroType(m->macroexp()));

}else{

t->add(m->identifier()->value(),new MacroIndexType(m->parametr(),m->macroexp()));

}

} else if(typeid(*current)==typeid(DeclConst)){

DeclConst *c=dynamic_cast<DeclConst*>(current);

Expr* v=c->val()->reduce();

if(typeid(*v)== typeid(ConstantInt)){

t->add(c->idetifier()->value(),new ConstIntType(dynamic_cast<ConstantInt*>(v)->value()));

} else if(typeid(*v)== typeid(ConstantFloat)){

t->add(c->idetifier()->value(),new ConstFloatType(dynamic_cast<ConstantFloat*>(v)->value()));

}

} else if (typeid(*current)==typeid(DeclArray)){

DeclArray* a=dynamic_cast<DeclArray*>(current);

t->add(a->arr()->value(),new ArrayType(a->dimension()->value()));

} else if (typeid(*current)==typeid(DeclCount)){

DeclCount* cnt=dynamic_cast<DeclCount*>(current);

t->add(cnt->count()->value(),new CountType(makeList(cnt->listInter())));

}

d=dynamic_cast<Seq*>(d->rest());

}

Seq* cp=program->classicpart();

// implicit declaration in classic part - var type

while(cp!=0){

Stmt* current=cp->first();

if(current==0) break;

if(typeid(*current)== typeid(Equation)){

Equation* e=dynamic_cast<Equation*>(current);

ObjType * l= t->lookup(e->lval()->value());

if( l == 0){

t->add(e->lval()->value(),new VarType);

} else if(typeid(*l) != typeid(VarType) ){

e->lval()->error("lvalue isn't var type:"+e->lval()->value());

}

} else if( typeid(*current)== typeid(EquationIndex)){

EquationIndex* ei=dynamic_cast<EquationIndex*>(current);

ObjType* l=t->get(ei->lval()->arr()->value());

if(typeid(*l)!= typeid(ArrayType)){

ei->lval()->error("indexing for no array type:"+ei->lval()->arr()->value());

}

}

cp=dynamic_cast<Seq*>(cp->rest());

}

// implicit declaration in hybrid part - var type

Seq* hp=program->hybridpart();

while(hp!=0){

Stmt* current=hp->first();

if(current==0) break;

LocalState* ls=dynamic_cast<LocalState*>(current);

Seq * body=ls->b();

while(body!=0){

Stmt* current=body->first();

if(current==0) break;

if(typeid(*current)== typeid(Equation)){

Equation* e=dynamic_cast<Equation*>(current);

ObjType * l= t->lookup(e->lval()->value());

if( l == 0){

t->add(e->lval()->value(),new VarType);

} else if(typeid(*l) != typeid(VarType) ){

e->lval()->error("lvalue isn't var type:"+e->lval()->value());

}

} else if( typeid(*current)== typeid(EquationIndex)){

EquationIndex* ei=dynamic_cast<EquationIndex*>(current);

ObjType* l=t->get(ei->lval()->arr()->value());

if(typeid(*l)!= typeid(ArrayType)){

ei->error("indexing for no array type:"+ei->lval()->arr()->value());

}

}

body=dynamic_cast<Seq*>(body->rest());

}

hp=dynamic_cast<Seq*>(hp->rest());

}

d=program->declarations();

while(d!=0){

Stmt* current=d->first();

if(current==0) break;

if(typeid(*current) == typeid(SetGlobal) ){

SetGlobal* sg=dynamic_cast<SetGlobal*>(current);

ObjType * l= t->lookup(sg->lval()->value());

if( l == 0){

Expr* rval=sg->body()->reduce();

if(typeid(*rval)== typeid(ConstantInt)){

t->add(sg->lval()->value(),new ConstIntType(dynamic_cast<ConstantInt*>(rval)->value()));

} else if(typeid(*rval)== typeid(ConstantFloat)){

t->add(sg->lval()->value(),new ConstFloatType(dynamic_cast<ConstantFloat*>(rval)->value()));

}

delete rval;

} else if(typeid(*l) != typeid(VarType)){

sg->lval()->error("lvalue isn't var type:"+sg->lval()->value());

}

} else if(typeid(*current) == typeid(SetGlobalIndex)){

SetGlobalIndex* sgi=dynamic_cast<SetGlobalIndex*>(current);

if(typeid(*t->get(sgi->lval()->arr()->value()))!=typeid(ArrayType)){

sgi->lval()->error("indexing for no array type:"+sgi->lval()->arr()->value());

}

}

d=dynamic_cast<Seq*>(d->rest());

}

return t;

}

};

}// parser_LL1

#endif // SYMBOLTABLEFACTORY_H