Util: Move literal validation logic to Parser
This commit is contained in:
+34
-40
@@ -77,12 +77,33 @@ void Lexer::analyze()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'a':
|
||||||
|
case 'b':
|
||||||
|
case 'c':
|
||||||
|
case 'd':
|
||||||
|
case 'e':
|
||||||
case 'f':
|
case 'f':
|
||||||
|
case 'g':
|
||||||
|
case 'h':
|
||||||
|
case 'i':
|
||||||
|
case 'j':
|
||||||
|
case 'k':
|
||||||
|
case 'l':
|
||||||
|
case 'm':
|
||||||
case 'n':
|
case 'n':
|
||||||
|
case 'o':
|
||||||
|
case 'p':
|
||||||
|
case 'q':
|
||||||
|
case 'r':
|
||||||
|
case 's':
|
||||||
case 't':
|
case 't':
|
||||||
|
case 'u':
|
||||||
|
case 'v':
|
||||||
|
case 'w':
|
||||||
|
case 'x':
|
||||||
|
case 'y':
|
||||||
|
case 'z':
|
||||||
if (!getLiteral()) {
|
if (!getLiteral()) {
|
||||||
// Error!
|
|
||||||
printf("Invalid JSON!\n");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -104,7 +125,7 @@ void Lexer::analyze()
|
|||||||
// Error!
|
// Error!
|
||||||
m_tokens->push_back({ Token::Type::None, m_line, m_column, std::string(1, peek()) });
|
m_tokens->push_back({ Token::Type::None, m_line, m_column, std::string(1, peek()) });
|
||||||
m_job->printErrorLine(m_tokens->back(),
|
m_job->printErrorLine(m_tokens->back(),
|
||||||
("unexpected character '" + std::string(1, peek()) + "'").c_str());
|
(std::string() + "unexpected character '" + peek() + "'").c_str());
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -186,16 +207,16 @@ bool Lexer::getString()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Lexer::getNumber()
|
bool Lexer::getNumberOrLiteral(Token::Type type)
|
||||||
{
|
{
|
||||||
size_t column = m_column;
|
size_t column = m_column;
|
||||||
std::string symbol = "";
|
std::string symbol = "";
|
||||||
std::string breakOnGrammar = std::string() + "{}[]:,\"" + '\n';
|
std::string breakOnGrammar = std::string() + "{}[]:,\" " + '\t' + '\r' + '\n';
|
||||||
|
|
||||||
for (char character;;) {
|
for (char character;;) {
|
||||||
character = peek();
|
character = peek();
|
||||||
|
|
||||||
// Break on all valid JSON grammar thats not a number
|
// Break on all valid JSON grammar thats not a number or literal
|
||||||
if (breakOnGrammar.find(character) != std::string::npos) {
|
if (breakOnGrammar.find(character) != std::string::npos) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -207,46 +228,19 @@ bool Lexer::getNumber()
|
|||||||
m_index--;
|
m_index--;
|
||||||
m_column--;
|
m_column--;
|
||||||
|
|
||||||
printf("Pushing -> Number: \"%s\"\t%zu[%zu]\n", symbol.c_str(), m_line, column);
|
m_tokens->push_back({ type, m_line, column, symbol });
|
||||||
m_tokens->push_back({ Token::Type::Number, m_line, column, symbol });
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Lexer::getNumber()
|
||||||
|
{
|
||||||
|
return getNumberOrLiteral(Token::Type::Number);
|
||||||
|
}
|
||||||
|
|
||||||
bool Lexer::getLiteral()
|
bool Lexer::getLiteral()
|
||||||
{
|
{
|
||||||
size_t index = m_index;
|
return getNumberOrLiteral(Token::Type::Literal);
|
||||||
size_t column = m_column;
|
|
||||||
|
|
||||||
std::string symbol = "";
|
|
||||||
|
|
||||||
char character;
|
|
||||||
for (;;) {
|
|
||||||
character = peek();
|
|
||||||
|
|
||||||
// Literals can only contain lower-case letters
|
|
||||||
if (character < 97 || character > 122) { // a-z
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_index++;
|
|
||||||
m_column++;
|
|
||||||
symbol += character;
|
|
||||||
}
|
|
||||||
m_index--;
|
|
||||||
m_column--;
|
|
||||||
|
|
||||||
// Literal name validation
|
|
||||||
if (symbol != "false" && symbol != "null" && symbol != "true") {
|
|
||||||
m_index = index;
|
|
||||||
m_column = column;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Pushing -> Literal: \"%s\"\t%zu[%zu]\n", symbol.c_str(), m_line, column);
|
|
||||||
m_tokens->push_back({ Token::Type::Literal, m_line, column, symbol });
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Json
|
} // namespace Json
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ private:
|
|||||||
bool consumeSpecific(char character);
|
bool consumeSpecific(char character);
|
||||||
|
|
||||||
bool getString();
|
bool getString();
|
||||||
|
bool getNumberOrLiteral(Token::Type type);
|
||||||
bool getNumber();
|
bool getNumber();
|
||||||
bool getLiteral();
|
bool getLiteral();
|
||||||
|
|
||||||
|
|||||||
+22
-29
@@ -44,16 +44,7 @@ Value Parser::parse()
|
|||||||
|
|
||||||
switch (token.type) {
|
switch (token.type) {
|
||||||
case Token::Type::Literal:
|
case Token::Type::Literal:
|
||||||
if (token.symbol == "null") {
|
result = getLiteral();
|
||||||
result = nullptr;
|
|
||||||
}
|
|
||||||
else if (token.symbol == "true") {
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
else if (token.symbol == "false") {
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
m_index++;
|
|
||||||
break;
|
break;
|
||||||
case Token::Type::Number:
|
case Token::Type::Number:
|
||||||
result = getNumber();
|
result = getNumber();
|
||||||
@@ -123,6 +114,24 @@ bool Parser::consumeSpecific(Token::Type type)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value Parser::getLiteral()
|
||||||
|
{
|
||||||
|
Token token = consume();
|
||||||
|
|
||||||
|
if (token.symbol == "null") {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
else if (token.symbol == "true") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (token.symbol == "false") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_job->printErrorLine(token, "invalid literal");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
Value Parser::getNumber()
|
Value Parser::getNumber()
|
||||||
{
|
{
|
||||||
Token token = consume();
|
Token token = consume();
|
||||||
@@ -238,16 +247,7 @@ Value Parser::getArray()
|
|||||||
|
|
||||||
if (token.type == Token::Type::Literal) {
|
if (token.type == Token::Type::Literal) {
|
||||||
printf("Adding literal to array.. v:{%s}, t:{%d}\n", token.symbol.c_str(), (int)token.type);
|
printf("Adding literal to array.. v:{%s}, t:{%d}\n", token.symbol.c_str(), (int)token.type);
|
||||||
if (token.symbol == "null") {
|
array.emplace_back(getLiteral());
|
||||||
array.emplace_back(nullptr);
|
|
||||||
}
|
|
||||||
else if (token.symbol == "true") {
|
|
||||||
array.emplace_back(true);
|
|
||||||
}
|
|
||||||
else if (token.symbol == "false") {
|
|
||||||
array.emplace_back(false);
|
|
||||||
}
|
|
||||||
m_index++;
|
|
||||||
}
|
}
|
||||||
else if (token.type == Token::Type::Number) {
|
else if (token.type == Token::Type::Number) {
|
||||||
printf("Adding number to array.. v:{%s}, t:{%d} -> %f\n", token.symbol.c_str(), (int)token.type, std::stod(token.symbol));
|
printf("Adding number to array.. v:{%s}, t:{%d} -> %f\n", token.symbol.c_str(), (int)token.type, std::stod(token.symbol));
|
||||||
@@ -345,15 +345,8 @@ Value Parser::getObject()
|
|||||||
token = consume();
|
token = consume();
|
||||||
if (token.type == Token::Type::Literal) {
|
if (token.type == Token::Type::Literal) {
|
||||||
printf("Adding literal to object.. k:{%s}, v:{%s}, t:{%d}\n", key.c_str(), token.symbol.c_str(), (int)token.type);
|
printf("Adding literal to object.. k:{%s}, v:{%s}, t:{%d}\n", key.c_str(), token.symbol.c_str(), (int)token.type);
|
||||||
if (token.symbol == "null") {
|
m_index--;
|
||||||
object[key] = nullptr;
|
object[key] = getLiteral();
|
||||||
}
|
|
||||||
else if (token.symbol == "true") {
|
|
||||||
object[key] = true;
|
|
||||||
}
|
|
||||||
else if (token.symbol == "false") {
|
|
||||||
object[key] = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (token.type == Token::Type::Number) {
|
else if (token.type == Token::Type::Number) {
|
||||||
printf("Adding number to object.. k:{%s}, v:{%s}, t:{%d} -> %f\n", name.c_str(), token.symbol.c_str(), (int)token.type, std::stod(token.symbol));
|
printf("Adding number to object.. k:{%s}, v:{%s}, t:{%d} -> %f\n", name.c_str(), token.symbol.c_str(), (int)token.type, std::stod(token.symbol));
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ private:
|
|||||||
Token consume();
|
Token consume();
|
||||||
bool consumeSpecific(Token::Type type);
|
bool consumeSpecific(Token::Type type);
|
||||||
|
|
||||||
|
Value getLiteral();
|
||||||
Value getNumber();
|
Value getNumber();
|
||||||
Value getArray();
|
Value getArray();
|
||||||
Value getObject();
|
Value getObject();
|
||||||
|
|||||||
Reference in New Issue
Block a user