Added validator to catch more syntax errors in pattern code
This commit is contained in:
parent
896cad1fe0
commit
c863b2f65b
@ -22,6 +22,7 @@ add_executable(ImHex
|
|||||||
|
|
||||||
source/parser/lexer.cpp
|
source/parser/lexer.cpp
|
||||||
source/parser/parser.cpp
|
source/parser/parser.cpp
|
||||||
|
source/parser/validator.cpp
|
||||||
|
|
||||||
source/provider/file_provider.cpp
|
source/provider/file_provider.cpp
|
||||||
|
|
||||||
|
20
include/parser/validator.hpp
Normal file
20
include/parser/validator.hpp
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <hex.hpp>
|
||||||
|
|
||||||
|
#include "token.hpp"
|
||||||
|
#include "ast_node.hpp"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace hex::lang {
|
||||||
|
|
||||||
|
class Validator {
|
||||||
|
public:
|
||||||
|
Validator();
|
||||||
|
|
||||||
|
bool validate(const std::vector<ASTNode*>& ast);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -1,8 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "parser/ast_node.hpp"
|
#include "parser/ast_node.hpp"
|
||||||
#include "parser/parser.hpp"
|
|
||||||
#include "parser/lexer.hpp"
|
|
||||||
|
|
||||||
#include "views/view.hpp"
|
#include "views/view.hpp"
|
||||||
#include "views/pattern_data.hpp"
|
#include "views/pattern_data.hpp"
|
||||||
|
68
source/parser/validator.cpp
Normal file
68
source/parser/validator.cpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#include "parser/validator.hpp"
|
||||||
|
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace hex::lang {
|
||||||
|
|
||||||
|
Validator::Validator() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Validator::validate(const std::vector<ASTNode*>& ast) {
|
||||||
|
|
||||||
|
std::unordered_set<std::string> typeNames;
|
||||||
|
|
||||||
|
for (const auto &node : ast) {
|
||||||
|
switch (node->getType()) {
|
||||||
|
case ASTNode::Type::VariableDecl:
|
||||||
|
{
|
||||||
|
// Check for duplicate variable names
|
||||||
|
auto varDeclNode = static_cast<ASTNodeVariableDecl*>(node);
|
||||||
|
if (!typeNames.insert(varDeclNode->getVariableName()).second)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ASTNode::Type::TypeDecl:
|
||||||
|
{
|
||||||
|
// Check for duplicate type names
|
||||||
|
auto typeDeclNode = static_cast<ASTNodeTypeDecl*>(node);
|
||||||
|
if (!typeNames.insert(typeDeclNode->getTypeName()).second)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ASTNode::Type::Struct:
|
||||||
|
{
|
||||||
|
// Check for duplicate type name
|
||||||
|
auto structNode = static_cast<ASTNodeStruct*>(node);
|
||||||
|
if (!typeNames.insert(structNode->getName()).second)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check for duplicate member names
|
||||||
|
std::unordered_set<std::string> memberNames;
|
||||||
|
for (const auto &member : structNode->getNodes())
|
||||||
|
if (!memberNames.insert(static_cast<ASTNodeVariableDecl*>(member)->getVariableName()).second)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ASTNode::Type::Enum:
|
||||||
|
{
|
||||||
|
// Check for duplicate type name
|
||||||
|
auto enumNode = static_cast<ASTNodeEnum*>(node);
|
||||||
|
if (!typeNames.insert(enumNode->getName()).second)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check for duplicate constant names
|
||||||
|
std::unordered_set<std::string> constantNames;
|
||||||
|
for (const auto &[value, name] : enumNode->getValues())
|
||||||
|
if (!constantNames.insert(name).second)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,9 @@
|
|||||||
#include <random>
|
|
||||||
#include "views/view_pattern.hpp"
|
#include "views/view_pattern.hpp"
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
#include "parser/parser.hpp"
|
||||||
|
#include "parser/lexer.hpp"
|
||||||
|
#include "parser/validator.hpp"
|
||||||
#include "utils.hpp"
|
#include "utils.hpp"
|
||||||
|
|
||||||
namespace hex {
|
namespace hex {
|
||||||
@ -111,6 +114,7 @@ namespace hex {
|
|||||||
void ViewPattern::parsePattern(char *buffer) {
|
void ViewPattern::parsePattern(char *buffer) {
|
||||||
static hex::lang::Lexer lexer;
|
static hex::lang::Lexer lexer;
|
||||||
static hex::lang::Parser parser;
|
static hex::lang::Parser parser;
|
||||||
|
static hex::lang::Validator validator;
|
||||||
|
|
||||||
this->clearPatternData();
|
this->clearPatternData();
|
||||||
this->postEvent(Events::PatternChanged);
|
this->postEvent(Events::PatternChanged);
|
||||||
@ -127,6 +131,12 @@ namespace hex {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto validatorResult = validator.validate(ast);
|
||||||
|
if (!validatorResult) {
|
||||||
|
for(auto &node : ast) delete node;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto &varNode : findNodes<lang::ASTNodeVariableDecl>(lang::ASTNode::Type::VariableDecl, ast)) {
|
for (auto &varNode : findNodes<lang::ASTNodeVariableDecl>(lang::ASTNode::Type::VariableDecl, ast)) {
|
||||||
if (!varNode->getOffset().has_value())
|
if (!varNode->getOffset().has_value())
|
||||||
continue;
|
continue;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user