Browse Source

Util: Move literal validation logic to Parser

master
Riyyi 3 years ago
parent
commit
8800ff4f7a
  1. 74
      src/util/json/lexer.cpp
  2. 1
      src/util/json/lexer.h
  3. 51
      src/util/json/parser.cpp
  4. 1
      src/util/json/parser.h

74
src/util/json/lexer.cpp

@ -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::getLiteral() bool Lexer::getNumber()
{ {
size_t index = m_index; return getNumberOrLiteral(Token::Type::Number);
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; bool Lexer::getLiteral()
{
return getNumberOrLiteral(Token::Type::Literal);
} }
} // namespace Json } // namespace Json

1
src/util/json/lexer.h

@ -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();

51
src/util/json/parser.cpp

@ -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));

1
src/util/json/parser.h

@ -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();

Loading…
Cancel
Save