Browse Source

doAssignment() - new expression parser

master
Odilitime 5 years ago
parent
commit
96bf25ffe0
  1. 172
      src/parsers/scripting/javascript/JSParser.cpp

172
src/parsers/scripting/javascript/JSParser.cpp

@ -1,5 +1,4 @@ @@ -1,5 +1,4 @@
#include "JSParser.h"
#include <iostream>
#include "../../../StringUtils.h"
std::vector<std::string> JSParser::getTokens(const std::string &source) const {
@ -162,7 +161,169 @@ std::vector<std::string> JSParser::getTokens(const std::string &source) const { @@ -162,7 +161,169 @@ std::vector<std::string> JSParser::getTokens(const std::string &source) const {
bool doAssignment(js_scope &rootScope, std::string token) {
// FIXME: make sure = isn't in quotes or JSON?
// FIXME: double or triple equal differentiation
//std::cout << "looking at [" << it2 << "]" << std::endl;
//std::cout << "looking at [" << token << "]" << std::endl;
// document.documentElement.classList?($.hasClass=function(e,t){return e.classList.contains(t)},$.addClass=function(e,t){e.classList.add(t)},$.removeClass=function(e,t){e.classList.remove(t)}):($.hasClass=function(e,t){return-1!=(" "+e.className+" ").indexOf(" "+t+" ")},$.addClass=function(e,t){e.className=""===e.className?t:e.className+" "+t},$.removeClass=function(e,t){e.className=(" "+e.className+" ").replace(" "+t+" ","")})
std::vector<std::string> expression_parts;
size_t cursor;
size_t last = 0;
size_t quoteStart = 0;
size_t parenStart = 0;
size_t parenLevel = 0;
size_t trinaryLevel = 0;
unsigned char state = 0;
for (cursor = 0; cursor < token.length(); cursor++) {
if (state == 0) {
// =
// ||
// &&
// <, >, <=, >=, ==, ===, !=, !==
// +, -
// *, /, %
// ?, >>, <<
if (token[cursor] == '"') {
quoteStart = cursor;
state = 4;
} else
if (token[cursor] == '"') {
quoteStart = cursor;
state = 5;
} else
if (token[cursor] == '(') {
parenStart = cursor;
parenLevel++;
state = 8;
expression_parts.push_back(token.substr(last, cursor - 1)); last = cursor + 1;
expression_parts.push_back("(");
}
// single =
if (token[cursor] == '=' && token.length() > cursor + 1 && token[cursor + 1] != '=') {
//state = 1;
expression_parts.push_back(token.substr(last, cursor - 1)); last = cursor + 1;
expression_parts.push_back("=");
}
// ||
if (token[cursor] == '|' && token.length() > cursor + 1 && token[cursor + 1] == '|') {
expression_parts.push_back(token.substr(last, cursor - 1)); last = cursor + 1;
expression_parts.push_back("||");
}
if (token[cursor] == '&' && token.length() > cursor + 1 && token[cursor + 1] == '&') {
expression_parts.push_back(token.substr(last, cursor - 1)); last = cursor + 1;
expression_parts.push_back("&&");
}
if (token[cursor] == '>' && token.length() > cursor + 1 && token[cursor + 1] != '=' && token[cursor + 1] != '>') {
expression_parts.push_back(token.substr(last, cursor - 1)); last = cursor + 1;
expression_parts.push_back(">");
}
if (token[cursor] == '<' && token.length() > cursor + 1 && token[cursor + 1] != '=' && token[cursor + 1] != '<') {
expression_parts.push_back(token.substr(last, cursor - 1)); last = cursor + 1;
expression_parts.push_back("<");
}
if (token[cursor] == '<' && token.length() > cursor + 1 && token[cursor + 1] == '&') {
expression_parts.push_back(token.substr(last, cursor - 1)); last = cursor + 1;
expression_parts.push_back("<=");
}
if (token[cursor] == '>' && token.length() > cursor + 1 && token[cursor + 1] == '&') {
expression_parts.push_back(token.substr(last, cursor - 1)); last = cursor + 1;
expression_parts.push_back(">=");
}
if (token[cursor] == '=' && token.length() > cursor + 2 && token[cursor + 1] == '=' && token[cursor + 2] != '=') {
expression_parts.push_back(token.substr(last, cursor - 1)); last = cursor + 1;
expression_parts.push_back("==");
}
if (token[cursor] == '=' && token.length() > cursor + 2 && token[cursor + 1] == '=' && token[cursor + 2] == '=') {
expression_parts.push_back(token.substr(last, cursor - 1)); last = cursor + 1;
expression_parts.push_back("===");
}
if (token[cursor] == '!' && token.length() > cursor + 2 && token[cursor + 1] == '=' && token[cursor + 2] != '=') {
expression_parts.push_back(token.substr(last, cursor - 1)); last = cursor + 1;
expression_parts.push_back("!=");
}
if (token[cursor] == '!' && token.length() > cursor + 2 && token[cursor + 1] == '=' && token[cursor + 2] == '=') {
expression_parts.push_back(token.substr(last, cursor - 1)); last = cursor + 1;
expression_parts.push_back("!==");
}
// +
if (token[cursor] == '+') {
expression_parts.push_back(token.substr(last, cursor - 1)); last = cursor + 1;
expression_parts.push_back("+");
}
if (token[cursor] == '-') {
expression_parts.push_back(token.substr(last, cursor - 1)); last = cursor + 1;
expression_parts.push_back("+");
}
if (token[cursor] == '*') {
expression_parts.push_back(token.substr(last, cursor - 1)); last = cursor + 1;
expression_parts.push_back("*");
}
if (token[cursor] == '/') {
expression_parts.push_back(token.substr(last, cursor - 1)); last = cursor + 1;
expression_parts.push_back("/");
}
if (token[cursor] == '%') {
expression_parts.push_back(token.substr(last, cursor - 1)); last = cursor + 1;
expression_parts.push_back("%");
}
if (token[cursor] == '?') {
expression_parts.push_back(token.substr(last, cursor)); last = cursor + 1;
expression_parts.push_back("?");
trinaryLevel++;
state = 9;
}
} else if (state == 4) {
if (token[cursor] == '\'') {
if (token[cursor - 1] != '\\') {
std::string quote = token.substr(quoteStart + 1, cursor - quoteStart - 1);
expression_parts.push_back(quote);
//std::cout << "single quote: " << quote << std::endl;
state = 0;
}
}
} else if (state == 5) {
if (token[cursor] == '\'') {
if (token[cursor - 1] != '\\') {
std::string quote = token.substr(quoteStart + 1, cursor - quoteStart - 1);
expression_parts.push_back(quote);
//std::cout << "single quote: " << quote << std::endl;
state = 0;
}
}
} else if (state == 8) {
if (token[cursor] == '(') {
parenLevel++;
} else
if (token[cursor] == ')') {
parenLevel--;
if (!parenLevel) {
expression_parts.push_back(token.substr(last, cursor)); last = cursor;
expression_parts.push_back(")");
state = 0;
}
}
} else if (state == 9) {
if (token[cursor] == '?') {
trinaryLevel++;
} else
if (token[cursor] == ':') {
trinaryLevel--;
if (!trinaryLevel) {
expression_parts.push_back(token.substr(last, cursor)); last = cursor + 1;
expression_parts.push_back(":");
state = 0;
}
}
}
}
std::cout << "expression token[" << token << "]" << std::endl;
std::cout << "expression debug" << std::endl;
for(auto it : expression_parts) {
std::cout << "[" << it << "]" << std::endl;
}
std::cout << "expression end" << std::endl;
auto hasTripleEqual = token.find("===");
auto hasDoubleEqual = std::string::npos;
auto hasSingleEqual = std::string::npos;
@ -171,6 +332,7 @@ bool doAssignment(js_scope &rootScope, std::string token) { @@ -171,6 +332,7 @@ bool doAssignment(js_scope &rootScope, std::string token) {
} else {
// process === expression
std::cout << "JSParser:::doAssignment - strict compare not implemented" << std::endl;
//std::cout << "token[" << token << "]" << std::endl;
}
if (hasDoubleEqual == std::string::npos) {
hasSingleEqual = token.find("=");
@ -318,9 +480,9 @@ std::shared_ptr<JavaScript> JSParser::parse(const std::string &source) const { @@ -318,9 +480,9 @@ std::shared_ptr<JavaScript> JSParser::parse(const std::string &source) const {
} else {
// make sure function is parsed
// and step through tokens
std::cout << "functionCall[" << funcName << "] not implemented" << std::endl;
auto arguments = it.substr(parenStart, it.find(")"));
std::cout << "parameters[" << arguments << "]" << std::endl;
auto arguments = it.substr(parenStart + 1, it.find(")") - parenStart - 1);
std::cout << "functionCall[" << funcName << "](" << arguments << ") not implemented" << std::endl;
//std::cout << "parameters[" << arguments << "]" << std::endl;
}
} else {
std::cout << "expression before functionCall not implemented" << std::endl;

Loading…
Cancel
Save