Browse Source

initial JS parser

master
Odilitime 3 years ago
parent
commit
6350959e03

+ 142
- 0
src/parsers/scripting/javascript/JSParser.cpp View File

@@ -0,0 +1,142 @@
#include "JSParser.h"
#include <vector>
#include <map>
#include <iostream>

class js_scope {
public:
js_scope *parent;
js_scope() {
parent = nullptr;
}
std::map<std::string, std::string> variables;
};

std::shared_ptr<JavaScript> JSParser::parse(const std::string &source) const {
std::shared_ptr<JavaScript> ret = std::make_shared<JavaScript>();
std::shared_ptr<js_scope> global = std::make_shared<js_scope>();
std::cout << "source: " << source << "\n" << std::endl;
// tokenize it
unsigned int cursor;
int state = 0;
int last = 0;
int quoteStart = 0;
int scopeLevel = 0;
int jsonStart = 0;
int jsonLevel = 0;
int functionStart = 0;
// each token is one statement
std::vector<std::string> tokens;
for (cursor = 0; cursor < source.length(); cursor++) {
if (state == 0) {
if (source[cursor] == '{') {
state = 1; // JSON
jsonStart = cursor;
jsonLevel++;
//std::cout << "Entering JSON: " << cursor << std::endl;
} else if (source[cursor] == '\'') { // quotes just for allowing [;{}\n] in quotes
quoteStart = cursor;
state = 4;
} else if (source[cursor] == '"') {
quoteStart = cursor;
state = 5;
} else if (source[cursor] == '/' && source.length() > cursor + 1 && source[cursor + 1] == '/') {
// single line comment
state = 2;
} else if (source[cursor] == '/' && source.length() > cursor + 1 && source[cursor + 1] == '*') {
// Multiline comment
state = 3;
} else if (source[cursor] == 'v' && source.length() > cursor + 3 && source[cursor + 1] == 'a'
&& source[cursor + 2] == 'r' && source[cursor + 3] == ' ') {
// var
state = 7;
} else if (source[cursor] == 'f' && source.length() > cursor + 8 && source[cursor + 1] == 'u'
&& source[cursor + 2] == 'n' && source[cursor + 3] == 'c' && source[cursor + 4] == 't'
&& source[cursor + 5] == 'i' && source[cursor + 6] == 'o' && source[cursor + 7] == 'n') {
//std::cout << "Entering function: " << cursor << std::endl;
state = 6;
functionStart = cursor;
}
} else if (state == 1) {
// inside a scope (JSON)
if (source[cursor] == '{') {
jsonLevel++;
} else
if (source[cursor] == '}') {
jsonLevel--;
if (!jsonLevel) {
std::cout << "Exiting JSON: " << source.substr(jsonStart, cursor - jsonStart) << std::endl;
state = 0; // exit JSON
}
}
} else if (state == 2) {
// inside a single line comment
if (source[cursor] == '\n') {
state = 0;
}
} else if (state == 3) {
// inside a multiline comment
if (source[cursor] == '*' && source.length() > cursor + 1 && source[cursor + 1] == '/') {
// end multiline comment
state = 0;
}
} else if (state == 4) {
// inside single quote
if (source[cursor] == '\'') {
if (source[cursor - 1] != '\\') {
//std::string quote = source.substr(quoteStart + 1, cursor - quoteStart - 1);
//std::cout << "single quote: " << quote << std::endl;
state = 0;
}
}
} else if (state == 5) {
// inside double quote
if (source[cursor] == '"') {
if (source[cursor - 1] != '\\') {
//std::string quote = source.substr(quoteStart + 1, cursor - quoteStart - 1);
//std::cout << "double quote: " << quote << std::endl;
state = 0;
}
}
} else if (state == 7) {
}
//
if (source[cursor] == '{') {
scopeLevel++;
}
bool endIt = false;
if (source[cursor] == '}') {
scopeLevel--;
if (state == 6 && !scopeLevel) {
std::cout << "Exiting function: " << source.substr(functionStart, cursor - functionStart) << std::endl;
state = 0;
endIt = true;
}
}

// state 0 or 7, ignore states 1-6
if ((state == 0 || state == 7) && !scopeLevel) {
if (source[cursor] == '\n' || source[cursor] == ';' || endIt) {
// FIXME: ; in for loops
std::string token = source.substr(last ? last + 1 : last, last ? (cursor - last - 1) : cursor );
if (source[cursor] == '}') {
token += '}';
}
// scopeLevel[" << scopeLevel << "]"
std::cout << "got token [" << token << "] ending[" << source[cursor] << "] endIt[" << endIt << "]" << std::endl;
tokens.push_back(token);
last = cursor;
if (state == 7) { // allow var constructs to end normally and take us out of var construct
state = 0; // reset state
}
}
}
}
std::cout << "out of characters in state " << state << std::endl;
std::string token = source.substr(last ? last + 1 : last, last ? (cursor - last - 1) : cursor );
tokens.push_back(token);
std::cout << "got token [" << token << "] ending[" << source[cursor] << "]" << std::endl;
return ret;
}

+ 15
- 0
src/parsers/scripting/javascript/JSParser.h View File

@@ -0,0 +1,15 @@
#ifndef JSPARSER_H
#define JSPARSER_H

#include <string>

class JavaScript {

};

class JSParser {
public:
std::shared_ptr<JavaScript> parse(const std::string &javascript) const;
};

#endif

Loading…
Cancel
Save