Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
98a707b
Update KmerIndex.cpp
mboffelli Jan 31, 2024
5f0f02a
Update KmerIndex.cpp
mboffelli Feb 2, 2024
60e991c
Write bubbles to separate files
mboffelli Feb 2, 2024
7da4439
Add opt.bubble
mboffelli Feb 2, 2024
8100c3d
Merge branch 'main' of https://github.com/mboffelli/klue
mboffelli Feb 2, 2024
15ee9bb
fix global declaration
mboffelli Feb 2, 2024
f833515
Add NAND, XOR, and parentheses matching validation
mboffelli Feb 6, 2024
b41e4b3
Fix parsing
mboffelli Feb 6, 2024
5cd458c
Add bubble detection (only SNPs, any kmer length)
mboffelli Mar 4, 2024
3bd02c4
Fix bubble (any variation and kmer length)
mboffelli Mar 4, 2024
395b145
update --extend
mboffelli Mar 4, 2024
a103ceb
update --extend
mboffelli Mar 5, 2024
3190537
fix --bubble
mboffelli Mar 5, 2024
62b51aa
update --bubble
mboffelli Mar 5, 2024
462ea4b
fix --bubble
mboffelli Mar 7, 2024
a569b2e
fix --bubble
mboffelli Mar 7, 2024
3f3bbc3
--bubble switch directions
mboffelli Mar 7, 2024
c3fef73
Update KmerIndex.cpp
mboffelli Mar 11, 2024
fcf0c5a
Update KmerIndex.cpp
mboffelli Mar 13, 2024
592fe5b
fix --bubble
mboffelli Mar 14, 2024
2b12859
modify --bubble to explore ALL possible
mboffelli Mar 15, 2024
c0c4d8b
Update KmerIndex.cpp
mboffelli Mar 15, 2024
5155a99
extended --bubble
mboffelli Mar 19, 2024
44560d1
Update KmerIndex.cpp
mboffelli Mar 19, 2024
3b9916a
fix duplicate revcomp in --bubble
mboffelli Mar 21, 2024
2a5aa00
Update KmerIndex.cpp
mboffelli Mar 21, 2024
301745b
Change --bubble
mboffelli Apr 2, 2024
590bf73
Update KmerIndex.cpp
mboffelli Apr 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 78 additions & 33 deletions src/ExpressionParser.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
#include "ExpressionParser.h"
#include <stdexcept>
#include <algorithm>
#include <iterator>
#include <iostream>

ExpressionParser::ExpressionParser(const std::string& input) : input(input) { tokenize(this->input); }
Node::Node(char v) : value(v), left(nullptr), right(nullptr) {}

Node* ExpressionParser::parse() {
size_t index = 0;
return parseExpression(index);
Node::~Node() {
delete left;
delete right;
}

ExpressionParser::ExpressionParser(const std::string& input) : input(input), currentIndex(0) {
tokenize(this->input);
}

std::vector<Token> ExpressionParser::tokenize(const std::string& input) {
tokens.clear();
int open_pars = 0;
for (char c : input) {
switch (c) {
case 'U':
Expand All @@ -22,53 +31,89 @@ std::vector<Token> ExpressionParser::tokenize(const std::string& input) {
break;
case '(':
tokens.push_back(Token(OPEN_PAR, c));
open_pars++;
break;
case ')':
tokens.push_back(Token(CLOSE_PAR, c));
open_pars--;
break;
default: // A, B, C, etc.
case 'N':
tokens.push_back(Token(NAND, c));
break;
case 'X':
tokens.push_back(Token(XOR, c));
break;
default:
tokens.push_back(Token(VALUE, c));
break;
}
}
if (open_pars != 0) {
throw std::runtime_error("[WARNING]: Unmatched parentheses in input.");
}
return tokens;
}

Node* ExpressionParser::parsePrimary(size_t& index) {
if (index >= tokens.size()) return nullptr;
Node* ExpressionParser::parse() {
currentIndex = 0;
Node* result = parseExpression();
if (currentIndex != tokens.size()) {
throw std::runtime_error("[WARNING]: Unexpected tokens after parsing.");
}
return result;
}

Node* node = nullptr;
Node* ExpressionParser::parseExpression() {
return parseUnionIntersection();
}

if (tokens[index].type == VALUE) {
node = new Node(tokens[index].value);
index++;
}
else if (tokens[index].type == OPEN_PAR) {
index++; // consume '('
node = parseExpression(index);
if (index < tokens.size() && tokens[index].type == CLOSE_PAR) {
index++; // consume ')'
}
Node* ExpressionParser::parseUnionIntersection() {
Node* node = parseDifferenceNandXor();
while (currentIndex < tokens.size() &&
(tokens[currentIndex].type == UNION || tokens[currentIndex].type == INTERSECT)) {
Token op = tokens[currentIndex++];
Node* right = parseDifferenceNandXor();
node = createNodeForToken(op, node, right);
}

return node;
}

Node* ExpressionParser::parseExpression(size_t& index) {
if (index >= tokens.size()) return nullptr;

Node* left = parsePrimary(index);

while (index < tokens.size() && (tokens[index].type == UNION || tokens[index].type == INTERSECT || tokens[index].type == DIFFERENCE)) {
Node* operation = new Node(tokens[index].value);
index++; // consume operation
Node* ExpressionParser::parseDifferenceNandXor() {
Node* node = parsePrimary();
while (currentIndex < tokens.size() &&
(tokens[currentIndex].type == DIFFERENCE || tokens[currentIndex].type == NAND || tokens[currentIndex].type == XOR)) {
Token op = tokens[currentIndex++];
Node* right = parsePrimary();
node = createNodeForToken(op, node, right);
}
return node;
}

Node* right = parsePrimary(index);
Node* ExpressionParser::parsePrimary() {
if (currentIndex >= tokens.size()) throw std::runtime_error("[WARNING]: Incomplete expression.");
Token token = tokens[currentIndex];

operation->left = left;
operation->right = right;
left = operation; // the current operation becomes the new left operand for the next loop iteration
if (token.type == OPEN_PAR) {
currentIndex++; // Skip '('
Node* node = parseExpression();
if (currentIndex >= tokens.size() || tokens[currentIndex].type != CLOSE_PAR) {
throw std::runtime_error("[WARNING]: Missing closing parenthesis.");
}
currentIndex++; // Skip ')'
return node;
}
else if (token.type == VALUE) {
currentIndex++;
return new Node(token.value);
}
else {
throw std::runtime_error("[WARNING]: Unexpected token.");
}

return left;
}

Node* ExpressionParser::createNodeForToken(const Token& token, Node* left, Node* right) {
Node* node = new Node(token.value);
node->left = left;
node->right = right;
return node;
}
18 changes: 12 additions & 6 deletions src/ExpressionParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,34 @@

#include <vector>
#include <string>
#include <map>
#include <set>
#include <sstream>

// Enum for token type
enum TokenType {
VALUE,
UNION,
INTERSECT,
DIFFERENCE,
NAND,
XOR,
OPEN_PAR,
CLOSE_PAR
};

// Token structure
struct Token {
TokenType type;
char value;
Token(TokenType t, char v) : type(t), value(v) {}
};

// Node structure for the binary tree
struct Node {
char value;
Node* left;
Node* right;

Node(char v) : value(v), left(nullptr), right(nullptr) {}
Node(char v);
~Node();
};

class ExpressionParser {
Expand All @@ -40,9 +42,13 @@ class ExpressionParser {
private:
std::string input;
std::vector<Token> tokens;
size_t currentIndex;

Node* parsePrimary(size_t& index);
Node* parseExpression(size_t& index);
Node* parseExpression();
Node* parseUnionIntersection();
Node* parseDifferenceNandXor();
Node* parsePrimary();
Node* createNodeForToken(const Token& token, Node* left, Node* right);
};

#endif // EXPRESSION_PARSER_H
Loading