Advertisement
Guest User

nik

a guest
Dec 11th, 2017
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.74 KB | None | 0 0
  1. /*
  2. * parser.h
  3. *
  4. * Created on: Oct 23, 2017
  5. * Author: gerardryan
  6. */
  7.  
  8. #ifndef PARSER_H_
  9. #define PARSER_H_
  10.  
  11. #include <iostream>
  12. using std::istream;
  13.  
  14. #include <string>
  15. #include <map>
  16. using std::string;
  17. using std::stoi;
  18. using std::map;
  19.  
  20. #include "lexer.h"
  21.  
  22. extern void error(int linenum, const string& message);
  23. extern void semanticError(int linenum, const string& message);
  24.  
  25. enum TypeForNode { INT_TYPE, STRING_TYPE, ERROR_TYPE };
  26.  
  27. class Value {
  28. TypeForNode type;
  29. int ival;
  30. string sval;
  31.  
  32. public:
  33. Value(TypeForNode t = ERROR_TYPE) : type(t), ival(0) {}
  34.  
  35. TypeForNode GetType() const { return type; }
  36.  
  37. int GetIntValue() const {
  38. if( type == INT_TYPE ) return ival;
  39. throw "This variable is not an int";
  40. }
  41. void SetIntValue(int v) {
  42. if( type == INT_TYPE ) ival = v;
  43. throw "This variable is not an int";
  44. }
  45.  
  46. string GetStringValue() const {
  47. if( type == STRING_TYPE ) return sval;
  48. throw "This variable is not a string";
  49. }
  50. void SetStringValue(string v) {
  51. if( type == STRING_TYPE ) sval = v;
  52. throw "This variable is not a string";
  53. }
  54.  
  55. Value operator+(const Value& v){
  56. TypeForNode myType = this->GetType();
  57. TypeForNode otherType = v.GetType();
  58. Value out = Value();
  59.  
  60. if(myType == otherType && myType == INT_TYPE){
  61. out = Value(INT_TYPE);
  62. out.setIntValue(this->GetIntValue() + v.GetIntValue());
  63. }
  64. else if(myType == otherType && myType == STRING_TYPE){
  65. out = Value(STRING_TYPE);
  66. out.setIntValue(this->GetStringValue() + v.GetStringValue());
  67. }
  68.  
  69. return out;
  70. }
  71.  
  72. Value operator-(const Value& v){
  73. return Value();
  74. }
  75. Value operator*(const Value& v){
  76. return Value();
  77. }
  78. Value operator/(const Value& v){
  79. return Value();
  80. }
  81.  
  82. };
  83.  
  84. extern map<string,Value> SymbolTable;
  85.  
  86. class ParseTree {
  87. int linenumber;
  88. ParseTree *left;
  89. ParseTree *right;
  90.  
  91. public:
  92. ParseTree(int n, ParseTree *l = 0, ParseTree *r = 0) : linenumber(n), left(l), right(r) {}
  93. virtual ~ParseTree() {}
  94.  
  95. ParseTree* getLeft() const { return left; }
  96. ParseTree* getRight() const { return right; }
  97. int getLineNumber() const { return linenumber; }
  98.  
  99. virtual TypeForNode GetType() const { return ERROR_TYPE; }
  100. virtual int GetIntValue() const { throw "no integer value"; }
  101. virtual string GetStringValue() const { throw "no string value"; }
  102. virtual Value eval() { return Value(); }
  103.  
  104. virtual int countSet() const { return 0; }
  105. virtual int countPlus() const { return 0; }
  106. virtual int countStar() const { return 0; }
  107.  
  108. virtual int findSemanticErrors() const { return 0; }
  109. };
  110.  
  111. class StatementList : public ParseTree {
  112. public:
  113. StatementList(ParseTree *first, ParseTree *rest) : ParseTree(0, first, rest) {}
  114.  
  115. Value eval(){
  116. if(this->getLeft() != 0)
  117. this->getLeft()->eval();
  118.  
  119. if(this->getRight() != 0)
  120. this->getRight()->eval();
  121.  
  122. return Value();
  123. }
  124.  
  125. };
  126.  
  127. class DeclStatement : public ParseTree {
  128. TypeForNode type;
  129. string id;
  130.  
  131. public:
  132. DeclStatement(int line, TypeForNode ty, string id) : ParseTree(line), type(ty), id(id) {}
  133.  
  134. Value eval(){
  135. if(findSemanticErrors()){
  136. SymbolTable[id]=this->getRight()->eval();
  137. }
  138. return Value();
  139. }
  140.  
  141. bool findSemanticErrors() {
  142. if( SymbolTable.find(id) != SymbolTable.end() ) {
  143. semanticError(this->getLineNumber(), "variable " + id + " was already declared");
  144. return false;
  145. }
  146. return true;
  147. }
  148.  
  149. };
  150.  
  151. class SetStatement : public ParseTree {
  152. string id;
  153.  
  154. public:
  155. SetStatement(int line, string id, ParseTree *ex) : ParseTree(line, ex), id(id) {}
  156. int countSet() const { return 1; }
  157.  
  158. Value eval(){
  159. return Value();
  160. }
  161.  
  162. int findSemanticErrors() const {
  163. if( SymbolTable.find(id) == SymbolTable.end() ) {
  164. semanticError(this->getLineNumber(), "variable " + id + " is used before being declared");
  165. return 1;
  166. }
  167. return 0;
  168. }
  169. };
  170.  
  171. class PrintStatement : public ParseTree {
  172. bool addNL;
  173.  
  174. public:
  175. PrintStatement(int line, bool isPrintln, ParseTree *ex) : ParseTree(line, ex), addNL(isPrintln) {}
  176.  
  177. Value eval(){
  178. return Value();
  179. }
  180.  
  181. void doprinting() const {
  182. if( addNL ) std::cout << std::endl;
  183. }
  184. };
  185.  
  186. class Addition : public ParseTree {
  187. public:
  188. Addition(int line, ParseTree *op1, ParseTree *op2) : ParseTree(line, op1, op2) {}
  189.  
  190. Value eval(){
  191. if(this->getLeft()->GetType() != this->getRight()->GetType()){
  192. //throw type error
  193. }
  194.  
  195. Value v = this->getLeft() + this->getRight();
  196. if(this->GetType() == ERROR_TYPE){
  197. //typeError
  198. }
  199. return v;
  200.  
  201. }
  202.  
  203. // will need to fill in type and value;
  204. // remember type is a function of
  205. int countPlus() const { return 1; }
  206. };
  207.  
  208. class Subtraction : public ParseTree {
  209. public:
  210. Subtraction(int line, ParseTree *op1, ParseTree *op2) : ParseTree(line, op1, op2) {}
  211.  
  212. // will need to fill in type and value;
  213. // remember type is a function of
  214. };
  215.  
  216. class Multiplication : public ParseTree {
  217. public:
  218. Multiplication(int line, ParseTree *op1, ParseTree *op2) : ParseTree(line, op1, op2) {}
  219.  
  220. // will need to fill in type and value;
  221. // remember type is a function of
  222. int countStar() const { return 1; }
  223. };
  224.  
  225. class Division : public ParseTree {
  226. public:
  227. virtual Value eval();
  228. Division(int line, ParseTree *op1, ParseTree *op2) : ParseTree(line, op1, op2) {}
  229.  
  230. // will need to fill in type and value;
  231. // remember type is a function of
  232. };
  233.  
  234. class IntegerConstant : public ParseTree {
  235. int value;
  236.  
  237. public:
  238. IntegerConstant(const Token& tok) : ParseTree(tok.GetLinenum()) {
  239. value = stoi( tok.GetLexeme() );
  240. }
  241. Value eval(){
  242. return Value();
  243. }
  244.  
  245. Value eval(){
  246. Value v = Value(INT_TYPE);
  247. v.setIntValue(value);
  248. return v;
  249. }
  250.  
  251.  
  252. TypeForNode GetType() const { return INT_TYPE; }
  253. int GetIntValue() const { return value; }
  254. };
  255.  
  256. class StringConstant : public ParseTree {
  257. string value;
  258.  
  259. public:
  260. Value eval(){
  261. return Value();
  262. }
  263. StringConstant(const Token& tok) : ParseTree(tok.GetLinenum()) {
  264. value = tok.GetLexeme();
  265. }
  266.  
  267. TypeForNode GetType() const { return STRING_TYPE; }
  268. string GetStringValue() const { return value; }
  269. };
  270.  
  271. class Identifier : public ParseTree {
  272. string value;
  273.  
  274. public:
  275. Identifier(const Token& tok) : ParseTree(tok.GetLinenum()) {
  276. value = tok.GetLexeme();
  277. }
  278.  
  279. Value eval(){
  280. //go into the symbol table and find the identifiers value
  281. //and return it
  282. return Value();
  283. }
  284.  
  285. TypeForNode GetType() const { return STRING_TYPE; }
  286. int GetIntValue() const { return 0; }
  287. string GetStringValue() const { return "foo"; }
  288.  
  289. int findSemanticErrors() const {
  290. if( SymbolTable.find(value) == SymbolTable.end() ) {
  291. semanticError(this->getLineNumber(), "variable " + value + " is used before being declared");
  292. return 1;
  293. }
  294. return 0;
  295. }
  296. };
  297.  
  298. extern ParseTree * Prog(istream* in);
  299. extern ParseTree * StmtList(istream* in);
  300. extern ParseTree * Stmt(istream* in);
  301. extern ParseTree * Decl(istream* in);
  302. extern ParseTree * Set(istream* in);
  303. extern ParseTree * Print(istream* in);
  304. extern ParseTree * Expr(istream* in);
  305. extern ParseTree * Term(istream* in);
  306. extern ParseTree * Primary(istream* in);
  307.  
  308.  
  309. #endif /* PARSER_H_ */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement