Skip to content

Commit be1b184

Browse files
Merge pull request #2 from Pip-Install-Party/officialblake-develop
continue logic
2 parents c947d3b + 65014a9 commit be1b184

File tree

5 files changed

+169
-24
lines changed

5 files changed

+169
-24
lines changed

Makefile

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
table.x: main.o commentDFA.o tokenizer.o parser.o table.o
2-
g++ -std=c++17 -g main.o commentDFA.o tokenizer.o parser.o table.o -o table.x
1+
tree.x: main.o commentDFA.o tokenizer.o parser.o table.o tree.o
2+
g++ -std=c++17 -g main.o commentDFA.o tokenizer.o parser.o table.o tree.o -o tree.x
33

44
main.o: main.cpp commentDFA.h tokenizer.h parser.h testFiles.h
55
g++ -std=c++17 -g main.cpp -o main.o -c
@@ -16,5 +16,8 @@ parser.o: parser.cpp parser.h
1616
table.o: table.cpp table.h
1717
g++ -std=c++17 -g table.cpp -o table.o -c
1818

19+
tree.o: tree.cpp tree.h
20+
g++ -std=c++17 -g tree.cpp -o tree.o -c
21+
1922
clean:
20-
rm -f table.x *.o *.txt
23+
rm -f tree.x *.o *.txt

main.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "tokenizer.h"
99
#include "parser.h"
1010
#include "table.h"
11+
#include "tree.h"
1112

1213
#include "testFiles.h"
1314

@@ -86,11 +87,29 @@ void symbolTable(std::ifstream& testFile, std::ostringstream& outputFile, int) {
8687
table->printParameters();
8788
}
8889

90+
void abstractSyntaxTree(std::ifstream& testFile, std::ostringstream& outputFile, int filenum) {
91+
CommentDFA *removeComments = new CommentDFA();
92+
std::ostringstream tempBuffer;
93+
removeComments->begin(testFile, tempBuffer);
94+
95+
Tokenizer *tokenizer = new Tokenizer();
96+
std::istringstream tokenStream(tempBuffer.str());
97+
tokenizer->begin(tokenStream);
98+
std::vector<Token> tokenList = tokenizer->getTokens();
99+
100+
Parser *parser = new Parser(tokenList);
101+
parser->begin();
102+
103+
Tree* tree = new Tree(parser->getHead());
104+
105+
}
106+
89107
const assignmentElements assignments[] = {
90108
{1, a1Tests, std::size(a1Tests), removeComments},
91109
{2, a2Tests, std::size(a2Tests), tokenize},
92110
{3, a3Tests, std::size(a3Tests), parse},
93-
{4, a4Tests, std::size(a4Tests), symbolTable}
111+
{4, a4Tests, std::size(a4Tests), symbolTable},
112+
{5, a5Tests, std::size(a5Tests), abstractSyntaxTree}
94113
};
95114

96115
// chooses test file based on user selection and includes error messages
@@ -113,10 +132,11 @@ int main() {
113132
<< "2 - Tokenize\n"
114133
<< "3 - Parse\n"
115134
<< "4 - Symbol Table\n"
135+
<< "5 - Abstract Syntax Tree\n"
116136
<< "Selection: ";
117137
std::cin >> assignmentNum;
118138

119-
if (assignmentNum < 1 || assignmentNum > 4) {
139+
if (assignmentNum < 1 || assignmentNum > 5) {
120140
std::cerr << "Invalid assignment choice. Exiting.\n";
121141
return 1;
122142
}

testFiles.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,13 @@ const std::filesystem::path a4Tests[] = {
4848
"Tests/Program4/programming_assignment_4-test_file_7.c"
4949
};
5050

51+
// Assignment 5
52+
const std::filesystem::path a5Tests[] = {
53+
"Tests/Program5/programming_assignment_5-test_file_1.c",
54+
"Tests/Program5/programming_assignment_5-test_file_2.c",
55+
"Tests/Program5/programming_assignment_5-test_file_3.c",
56+
"Tests/Program5/programming_assignment_5-test_file_4.c",
57+
"Tests/Program5/programming_assignment_5-test_file_5.c",
58+
};
59+
5160
#endif // TESTFILES_H

tree.cpp

Lines changed: 122 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,146 @@
11
#include "tree.h"
22

33
// Prints the abstract syntax tree to the provided output stream
4-
void Tree::printTree(Token* head){
4+
void Tree::printTree(Token* head, Token* prevToken){
5+
bool ignore = true;
56
if (head == nullptr){
67
return;
78
}
89
if (head->getValue() == "{") {
10+
ignore = false;
911
std::cout << "BEGIN BLOCK";
1012
} else if (head->getValue() == "}") {
13+
ignore = false;
1114
std::cout << "END BLOCK";
1215
} else if (head->getValue() == "procedure" || head->getValue() == "function") {
16+
std::cout << "DECLARATION\n|\n|\n|\n|\nv\n";
17+
while(head->getSibling() != nullptr) {
18+
head = head->getSibling();
19+
}
20+
} else if (head->getValue() == "if"){
21+
ignore = false;
22+
std::cout << "IF ----> ";
23+
// This needs to break out to handleAssignment();
24+
head = head->getSibling();
25+
head = handleAssignment(head);
26+
prevToken = nullptr;
27+
28+
}else if (contains(varTypes, prevToken->getValue())) {
29+
ignore = false;
1330
std::cout << "DECLARATION";
14-
} else if (contains(head->getValue())) {
15-
std::cout << "DECLARATION";
31+
if (head->getSibling() != nullptr && head->getSibling()->getValue() == ",") {
32+
while(head->getSibling() != nullptr) {
33+
head = head->getSibling();
34+
if (head->getType() == "IDENTIFIER") {
35+
std::cout << "\n|\n|\n|\n|\nv\nDECLARATION";
36+
}
37+
}
38+
}
1639
} else if (head->getType() == "IDENTIFIER") {
1740
if (head->getSibling() != nullptr && head->getSibling()->getValue() == "=") {
18-
std::cout << "ASSIGNMENT" << " ----> " << head->getValue();
41+
ignore = false;
42+
std::cout << "ASSIGNMENT" << " ----> ";
1943
// This needs to break out to handleAssignment();
20-
// head = handleAssignment();
21-
}
22-
}
44+
head = handleAssignment(head);
45+
prevToken = nullptr;
46+
}
47+
}
2348
if (head->getSibling() != nullptr) {
24-
head = head->getSibling();
25-
std::cout << " ----> ";
49+
if (!ignore){
50+
std::cout << " ----> ";
51+
std::cout << head->getValue();
52+
}
53+
return printTree(head->getSibling(), head);
2654
} else if (head->getChild() != nullptr) {
27-
head = head->getChild();
28-
std::cout << "\n|\n|\n|\n|\nv ";
29-
}
30-
return printTree(head);
55+
if (!ignore) {
56+
std::cout << "\n|\n|\n|\n|\nv\n ";
57+
}
58+
return printTree(head->getChild(), head);
59+
}
60+
return;
3161
}
3262

33-
bool contains(std::string type){
34-
for (const auto& reserved : varTypes) {
35-
if (type == reserved) {
63+
bool Tree::contains(const std::vector<std::string> reserved, std::string type){
64+
for (const auto& word : reserved) {
65+
if (type == word) {
3666
return true;
3767
}
3868
}
3969
return false;
70+
}
71+
72+
Token* Tree::handleAssignment(Token* head) {
73+
std::string equationAsString;
74+
equationAsString += head->getValue();
75+
head = head->getSibling();
76+
77+
while(contains(equationOperators, head->getValue()) || head->getType() == "IDENTIFIER" || head->getType() == "INTEGER" || head->getType() == "CHARACTER") {
78+
equationAsString += head->getValue();
79+
if (head ->getSibling() != nullptr) {
80+
head = head->getSibling();
81+
} else {
82+
break;
83+
}
84+
}
85+
//head = head->getSibling(); // Remove ?
86+
87+
for (char ch : infixToPostfix(equationAsString)) {
88+
// std::cout << ch << " ----> ";
89+
}
90+
std::cout << "Postfix Expression";
91+
return head;
92+
}
93+
94+
95+
// Function to get precedence of operators
96+
int Tree::getPrecedence(char op) {
97+
if (op == '+' || op == '-') return 1;
98+
if (op == '*' || op == '/') return 2;
99+
return 0;
100+
}
101+
102+
// Function to check if a character is an operator
103+
bool Tree::isOperator(char c) {
104+
return c == '+' || c == '-' || c == '*' || c == '/';
105+
}
106+
107+
// Function to convert infix expression to postfix
108+
std::string Tree::infixToPostfix(const std::string& infix) {
109+
std::stack<char> operators;
110+
std::string postfix;
111+
112+
for (char c : infix) {
113+
// If the character is an operand, add it to postfix output
114+
if (std::isdigit(c) || std::isalpha(c)) {
115+
postfix += c;
116+
}
117+
// If the character is '(', push it onto the stack
118+
else if (c == '(') {
119+
operators.push(c);
120+
}
121+
// If the character is ')', pop and add operators until '(' is found
122+
else if (c == ')') {
123+
while (!operators.empty() && operators.top() != '(') {
124+
postfix += operators.top();
125+
operators.pop();
126+
}
127+
operators.pop(); // Pop '(' from the stack
128+
}
129+
// If the character is an operator
130+
else if (isOperator(c)) {
131+
while (!operators.empty() && getPrecedence(operators.top()) >= getPrecedence(c)) {
132+
postfix += operators.top();
133+
operators.pop();
134+
}
135+
operators.push(c);
136+
}
137+
}
138+
139+
// Pop all remaining operators in the stack
140+
while (!operators.empty()) {
141+
postfix += operators.top();
142+
operators.pop();
143+
}
144+
145+
return postfix;
40146
}

tree.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,20 @@
44
#include "token.h"
55

66
const std::vector<std::string> varTypes = {"int", "void", "char", "bool", "string", "short", "long"};
7+
const std::vector<std::string> equationOperators = {"+", "-", "/", "%", "*", "(", ")", "=", "'", "<", ">", "<=", ">=", "&&"};
78

89
class Tree {
910
private:
10-
void printTree(Token*);
11-
bool contains(std::string);
11+
void printTree(Token*, Token*);
12+
bool contains(const std::vector<std::string>, std::string);
13+
Token* handleAssignment(Token*);
14+
int getPrecedence(char op);
15+
bool isOperator(char c);
16+
std::string infixToPostfix(const std::string& infix);
17+
18+
1219
public:
13-
Tree(Token* head) { printTree(head); }
20+
Tree(Token* head) { printTree(head, nullptr); }
1421
~Tree();
1522
};
1623

0 commit comments

Comments
 (0)