-
Notifications
You must be signed in to change notification settings - Fork 0
/
2005009_syntax.h
137 lines (118 loc) · 5.31 KB
/
2005009_syntax.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include "2005009_SymbolTable.h"
#include <typeinfo>
using namespace std;
ofstream lout;
ofstream eout;
ofstream pout;
int prevLine = 1;
extern int lineCount;
extern int errCount;
extern FILE *yyin;
vector<SymbolInfo*> tempParameterList;
int tableSize = 11;
SymbolTable *table = new SymbolTable(tableSize);
void errorPrint(int lineNo, string s) {
eout << "Line# " << lineNo << ": " << s << endl;
if(!s.find("Warning"))
errCount++;
}
void syntaxError(int lineNo, string type) {
if(lineNo == 0) lineNo = prevLine;
lout << "Error at line no "<< lineNo <<" : syntax error" << endl;
if(type == "parameter")
eout << "Line# " << lineNo << ": Syntax error at parameter list of function definition" << endl;
else if(type == "declaration")
eout << "Line# "<<lineNo<<": Syntax error at declaration list of variable declaration" << endl;
else if(type == "expression")
eout << "Line# "<< lineNo <<": Syntax error at expression of expression statement" << endl;
errCount++;
}
bool isValidTypeSpecifier(SymbolInfo* typeSpecifier, string name) {
if( typeSpecifier->getTypeSpecifier() == TypeSpecifier::_VOID ){
if(name == "")
errorPrint(typeSpecifier->getStartLine(), "Variable or field declared void");
else
errorPrint(typeSpecifier->getStartLine(), "Variable or field \'"+ name+ "\' declared void");
return false;
}
return true;
}
SymbolInfo* initialProcess(vector<SymbolInfo*> children, string type, string rule) {
string name = "";
if(children.size()>0) name += children[0]->getName();
for(int i=1; i<children.size(); i++) name += " " + children[i]->getName();
lout << type << " : " << rule << endl;
SymbolInfo* root;
if(children.size()>0)
root= new SymbolInfo(name, type, children[0]->getStartLine(), children[children.size()-1]->getEndLine(), rule);
else
root= new SymbolInfo(name, type, prevLine, prevLine, rule);
root->setChildren(children);
prevLine = lineCount;
return root;
}
void logPrint(string output) {
lout << output << endl;
}
TypeSpecifier getType(TypeSpecifier leftSymbol, TypeSpecifier rightSymbol) {
if( leftSymbol == TypeSpecifier::_VOID || rightSymbol == TypeSpecifier::_VOID ) return TypeSpecifier::_VOID;
if( leftSymbol == TypeSpecifier::_ERROR || rightSymbol == TypeSpecifier::_ERROR ) return TypeSpecifier::_ERROR;
if( leftSymbol == TypeSpecifier::_FLOAT || rightSymbol == TypeSpecifier::_FLOAT ) return TypeSpecifier::_FLOAT;
return TypeSpecifier::_INT;
}
void insertFunction(SymbolInfo* function, vector<SymbolInfo*> parameterList, TypeSpecifier typeSpecifier, SymbolType symbolType) {
function->setTypeSpecifier(typeSpecifier);
function->setParameters(parameterList);
function->setSymbolType(symbolType);
if(table->getCurrentScope()->getParentScope()!=NULL)
errorPrint(function->getStartLine(), "Wrong scoping of function \'" + function->getName()+ "\'");
if(table->_insert(function->getName(),function->getType(), function)) return;
if(symbolType == SymbolType::FUNCTION_DECLARATION) {
errorPrint(function->getStartLine(), "Redeclaration of function \'" + function->getName()+ "\'");
return;
}
SymbolInfo* prevSymbol = table->_lookUp(function->getName())->getPointTo();
if( prevSymbol->getSymbolType() != SymbolType::FUNCTION_DECLARATION ) {
errorPrint(function->getStartLine(), "\'" + function->getName() + "\' redeclared as different kind of symbol");
return;
}
if( prevSymbol->getTypeSpecifier() != function->getTypeSpecifier() )
errorPrint(function->getStartLine(), "Conflicting types for \'" + function->getName() +"\'");
if( prevSymbol->getParameters().size() != function->getParameters().size() )
errorPrint(function->getStartLine(), "Conflicting types for \'" + function->getName()+"\'");
else {
prevSymbol->setSymbolType(SymbolType::FUNCTION_DEFINITION);
vector<SymbolInfo*> paramsOfDeclaration = prevSymbol->getParameters(), paramsOfDefinition = function->getParameters();
int i = 0;
for(SymbolInfo* param: paramsOfDefinition) {
if( param->getTypeSpecifier() != paramsOfDeclaration[i]->getTypeSpecifier())
errorPrint(function->getStartLine(), to_string(i+1) + "th parameter mismatch in function " + function->getName());
else if( paramsOfDeclaration[i]->getSymbolType() != param->getSymbolType())
errorPrint(function->getStartLine(), to_string(i+1) + "th parameter mismatch in function " + function->getName());
i++;
}
prevSymbol->setParameters(paramsOfDefinition);
}
}
void updateParameterList(SymbolInfo* parent, vector<SymbolInfo*> parameterList, SymbolInfo* type, SymbolInfo* child = NULL) {
if(child == NULL)
child = new SymbolInfo("", "ID", type->getStartLine(), type->getEndLine());
child->setTypeSpecifier(type->getTypeSpecifier());
parent->setParameters(parameterList);
parent->addParameter(child);
isValidTypeSpecifier(type, child->getName());
tempParameterList = parent->getParameters();
}
void setType(SymbolInfo* symbol, TypeSpecifier type, TypeSpecifier trivial = TypeSpecifier::_NONE) {
if(type == TypeSpecifier::_VOID) {
errorPrint(symbol->getStartLine(), "Void cannot be used in expression");
symbol->setTypeSpecifier(TypeSpecifier::_ERROR);
} else if(type == TypeSpecifier::_ERROR) {
// errorPrint($1->getStartLine(), "Type mismatch in expression");
symbol->setTypeSpecifier(type);
} else if(trivial != TypeSpecifier::_NONE) {
symbol->setTypeSpecifier(trivial);
} else {
symbol->setTypeSpecifier(type);
}
}