Fixes empty script returning segmentation fault

This commit is contained in:
Deukhoofd 2019-09-14 10:35:32 +02:00
parent 45d3bc690b
commit b462c1b873
Signed by: Deukhoofd
GPG Key ID: ADF2E9256009EDCE
3 changed files with 69 additions and 50 deletions

View File

@ -37,17 +37,17 @@ namespace Porygon::Parser {
virtual ~ParsedStatement() = default;
virtual const ParsedStatementKind GetKind() const = 0;
[[nodiscard]] virtual ParsedStatementKind GetKind() const = 0;
const unsigned int GetStartPosition() const {
[[nodiscard]] unsigned int GetStartPosition() const {
return _start;
}
const unsigned int GetLength() const {
[[nodiscard]] unsigned int GetLength() const {
return _length;
}
const unsigned int GetEndPosition() const {
[[nodiscard]] unsigned int GetEndPosition() const {
return _start + _length - 1;
}
};
@ -56,7 +56,7 @@ namespace Porygon::Parser {
public:
ParsedBadStatement(unsigned int start, unsigned int length) : ParsedStatement(start, length) {};
inline const ParsedStatementKind GetKind() const final {
[[nodiscard]] inline ParsedStatementKind GetKind() const final {
return ParsedStatementKind::Bad;
}
};
@ -65,7 +65,7 @@ namespace Porygon::Parser {
public:
ParsedBreakStatement(unsigned int start, unsigned int length) : ParsedStatement(start, length) {};
inline const ParsedStatementKind GetKind() const final {
[[nodiscard]] inline ParsedStatementKind GetKind() const final {
return ParsedStatementKind::Break;
}
};
@ -73,10 +73,9 @@ namespace Porygon::Parser {
class ParsedBlockStatement : public ParsedStatement {
const std::vector<const ParsedStatement *> _statements;
public:
explicit ParsedBlockStatement(const std::vector<const ParsedStatement *>& statements)
: ParsedStatement(statements.front()->GetStartPosition(),
statements.back()->GetEndPosition() - statements.front()->GetStartPosition()),
_statements(statements) {}
explicit ParsedBlockStatement(std::vector<const ParsedStatement *> statements, size_t start, size_t length)
: ParsedStatement(start, length),
_statements(std::move(statements)) {}
ParsedBlockStatement(std::vector<const ParsedStatement *> statements, unsigned int start) : ParsedStatement(
start, 0), _statements(std::move(statements)) {
@ -89,21 +88,21 @@ namespace Porygon::Parser {
}
}
inline const ParsedStatementKind GetKind() const override {
[[nodiscard]] inline ParsedStatementKind GetKind() const override {
return ParsedStatementKind::Block;
}
inline const std::vector<const ParsedStatement *> *GetStatements() const {
[[nodiscard]] inline const std::vector<const ParsedStatement *> *GetStatements() const {
return &_statements;
}
};
class ParsedScriptStatement : public ParsedBlockStatement {
public:
explicit ParsedScriptStatement(vector<const ParsedStatement *> statements) : ParsedBlockStatement(
move(statements)) {}
explicit ParsedScriptStatement(const vector<const ParsedStatement *>& statements, size_t start, size_t length) : ParsedBlockStatement(
statements, start, length) {}
inline const ParsedStatementKind GetKind() const final {
[[nodiscard]] inline ParsedStatementKind GetKind() const final {
return ParsedStatementKind::Script;
}
};
@ -124,11 +123,11 @@ namespace Porygon::Parser {
_expression = nullptr;
}
inline const ParsedStatementKind GetKind() const final {
[[nodiscard]] inline ParsedStatementKind GetKind() const final {
return ParsedStatementKind::Expression;
}
inline const ParsedExpression *GetExpression() const {
[[nodiscard]] inline const ParsedExpression *GetExpression() const {
return _expression;
}
};
@ -151,19 +150,19 @@ namespace Porygon::Parser {
delete _block;
}
inline const ParsedStatementKind GetKind() const final {
[[nodiscard]] inline ParsedStatementKind GetKind() const final {
return ParsedStatementKind::FunctionDeclaration;
}
inline const HashedString GetIdentifier() const {
[[nodiscard]] inline HashedString GetIdentifier() const {
return _identifier;
}
inline const vector<TypedVariableIdentifier *> *GetParameters() const {
[[nodiscard]] inline const vector<TypedVariableIdentifier *> *GetParameters() const {
return &_parameters;
}
inline const ParsedBlockStatement *GetBlock() const {
[[nodiscard]] inline const ParsedBlockStatement *GetBlock() const {
return _block;
}
};
@ -182,19 +181,19 @@ namespace Porygon::Parser {
delete _expression;
}
inline const ParsedStatementKind GetKind() const final {
[[nodiscard]] inline ParsedStatementKind GetKind() const final {
return ParsedStatementKind::Assignment;
}
inline const bool IsLocal() const {
[[nodiscard]] inline bool IsLocal() const {
return _local;
}
inline const HashedString GetIdentifier() const {
[[nodiscard]] inline HashedString GetIdentifier() const {
return _identifier;
}
inline const ParsedExpression *GetExpression() const {
[[nodiscard]] inline const ParsedExpression *GetExpression() const {
return _expression;
}
};
@ -214,15 +213,15 @@ namespace Porygon::Parser {
delete _valueExpression;
}
inline const ParsedStatementKind GetKind() const final {
[[nodiscard]] inline ParsedStatementKind GetKind() const final {
return ParsedStatementKind::IndexAssignment;
}
inline const ParsedExpression *GetIndexExpression() const {
[[nodiscard]] inline const ParsedExpression *GetIndexExpression() const {
return _indexExpression;
}
inline const ParsedExpression *GetValueExpression() const {
[[nodiscard]] inline const ParsedExpression *GetValueExpression() const {
return _valueExpression;
}
};
@ -239,11 +238,11 @@ namespace Porygon::Parser {
delete _expression;
}
inline const ParsedStatementKind GetKind() const final {
[[nodiscard]] inline ParsedStatementKind GetKind() const final {
return ParsedStatementKind::Return;
}
inline const ParsedExpression *GetExpression() const {
[[nodiscard]] inline const ParsedExpression *GetExpression() const {
return _expression;
}
};
@ -273,19 +272,19 @@ namespace Porygon::Parser {
delete _elseStatement;
}
inline const ParsedStatementKind GetKind() const final {
[[nodiscard]] inline ParsedStatementKind GetKind() const final {
return ParsedStatementKind::Conditional;
}
inline const ParsedExpression *GetCondition() const {
[[nodiscard]] inline const ParsedExpression *GetCondition() const {
return _condition;
}
inline const ParsedStatement *GetBlock() const {
[[nodiscard]] inline const ParsedStatement *GetBlock() const {
return _block;
}
inline const ParsedStatement *GetElseStatement() const {
[[nodiscard]] inline const ParsedStatement *GetElseStatement() const {
return _elseStatement;
}
};
@ -310,27 +309,27 @@ namespace Porygon::Parser {
delete _block;
}
inline const ParsedStatementKind GetKind() const final {
[[nodiscard]] inline ParsedStatementKind GetKind() const final {
return ParsedStatementKind::NumericalFor;
}
inline const HashedString GetIdentifier() const{
[[nodiscard]] inline HashedString GetIdentifier() const{
return _identifier;
}
inline const ParsedExpression *GetStart() const{
[[nodiscard]] inline const ParsedExpression *GetStart() const{
return _start;
}
inline const ParsedExpression *GetEnd() const{
[[nodiscard]] inline const ParsedExpression *GetEnd() const{
return _end;
}
inline const ParsedExpression *GetStep() const{
[[nodiscard]] inline const ParsedExpression *GetStep() const{
return _step;
}
inline const ParsedStatement *GetBlock() const{
[[nodiscard]] inline const ParsedStatement *GetBlock() const{
return _block;
}
};
@ -352,23 +351,23 @@ namespace Porygon::Parser {
delete _block;
}
inline const ParsedStatementKind GetKind() const final {
[[nodiscard]] inline ParsedStatementKind GetKind() const final {
return ParsedStatementKind::GenericFor;
}
inline const HashedString GetKeyIdentifier() const{
[[nodiscard]] inline HashedString GetKeyIdentifier() const{
return _keyIdentifier;
}
inline const HashedString GetValueIdentifier() const{
[[nodiscard]] inline HashedString GetValueIdentifier() const{
return _valueIdentifier;
}
inline const ParsedExpression* GetIteratorExpression() const{
[[nodiscard]] inline const ParsedExpression* GetIteratorExpression() const{
return _iteratorExpression;
}
inline const ParsedStatement* GetBlock() const{
[[nodiscard]] inline const ParsedStatement* GetBlock() const{
return _block;
}
};
@ -386,15 +385,15 @@ namespace Porygon::Parser {
delete _block;
}
inline const ParsedStatementKind GetKind() const final {
[[nodiscard]] inline ParsedStatementKind GetKind() const final {
return ParsedStatementKind::While;
}
inline const ParsedExpression* GetCondition(){
[[nodiscard]] inline const ParsedExpression* GetCondition(){
return _condition;
}
inline const ParsedStatement* GetBlock(){
[[nodiscard]] inline const ParsedStatement* GetBlock(){
return _block;
}
};

View File

@ -16,7 +16,11 @@ namespace Porygon::Parser {
}
statements.push_back(this->ParseStatement(next));
}
return new ParsedScriptStatement(statements);
auto end = 0;
if (statements.size() > 0){
end = statements.back()->GetEndPosition();
}
return new ParsedScriptStatement(statements, 0, end);
}
inline const Token *Parser::Peek() {
@ -123,7 +127,11 @@ namespace Porygon::Parser {
if (statements.empty()) {
return new ParsedBlockStatement(statements, start);
}
return new ParsedBlockStatement(statements);
auto end = 0;
if (statements.size() > 0){
end = statements.back()->GetEndPosition();
}
return new ParsedBlockStatement(statements, start, end - start);
}
ParsedStatement *Parser::ParseFunctionDeclaration(const Token *current) {

View File

@ -5,6 +5,18 @@
#include "../../src/Parser/Parser.hpp"
using namespace Porygon::Parser;
TEST_CASE( "Parse empty script", "[parser]" ) {
vector<const Token*> v {
new SimpleToken(TokenKind::EndOfFile,0,0),
};
Parser parser = Parser(v, nullptr);
auto parsedScript = parser.Parse();
for (auto t : v){
delete t;
}
delete parsedScript;
}
TEST_CASE( "Parse single true keyword", "[parser]" ) {
vector<const Token*> v {new SimpleToken(TokenKind::TrueKeyword,0,0), new SimpleToken(TokenKind::EndOfFile,0,0)};
Parser parser = Parser(v, nullptr);