diff --git a/makefile b/makefile index c8fffa2..7d47ebf 100644 --- a/makefile +++ b/makefile @@ -11,7 +11,7 @@ $(TARGET): build/parser.o build/lexer.o build/main.o build/parser.cpp build/parser.hpp: src/parser.y | build $(BISON) -d -o build/parser.cpp src/parser.y -build/lexer.cpp build/lexer.hpp: src/lexer.l build/parser.hpp src/scanner.hpp src/indent_helper.hpp| build +build/lexer.cpp build/lexer.hpp: src/lexer.l build/parser.hpp src/scanner.hpp src/indent_stack.hpp| build $(FLEX) --header-file=build/lexer.hpp -o build/lexer.cpp src/lexer.l build/%.o: build/%.cpp diff --git a/src/indent_helper.hpp b/src/indent_stack.hpp similarity index 79% rename from src/indent_helper.hpp rename to src/indent_stack.hpp index e009ee0..4c6b2b5 100644 --- a/src/indent_helper.hpp +++ b/src/indent_stack.hpp @@ -9,15 +9,15 @@ enum class IndentAction constexpr int TAB_WIDTH = 8; -class IndentHelper +class IndentStack { std::stack indent_stack; int pending_dedents = 0; public: - IndentHelper() { indent_stack.push(0); } + IndentStack() { indent_stack.push(0); } - IndentAction processLine(int spaces) + IndentAction updateIndentation(int spaces) { int current = indent_stack.top(); @@ -32,7 +32,6 @@ public: return IndentAction::Indent; } - pending_dedents = 0; while (indent_stack.top() > spaces) { indent_stack.pop(); @@ -48,8 +47,7 @@ public: return IndentAction::None; } - // returns false on failure - bool consumeDedent() + bool popDedent() { if (pending_dedents <= 0) { @@ -68,4 +66,14 @@ public: } return spaces; } + + bool hasRemainingDedents() + { + return pending_dedents > 0; + } + + IndentAction closeBlock() + { + return updateIndentation(0); + } }; \ No newline at end of file diff --git a/src/lexer.l b/src/lexer.l index b603b70..de29239 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -5,7 +5,7 @@ %{ #include "scanner.hpp" -#include "indent_helper.hpp" +#include "indent_stack.hpp" %} @@ -14,8 +14,8 @@ ^[ \t]*#.*\n { /* Ignore comment-only lines */ } ^[ \t]* { - int col = indent_helper.calculateColumn(yytext, yyleng); - auto action = indent_helper.processLine(col); + int col = indent_stack.calculateColumn(yytext, yyleng); + auto action = indent_stack.updateIndentation(col); if (action == IndentAction::Indent) return yy::parser::token::TOK_INDENT; if (action == IndentAction::Dedent) return yy::parser::token::TOK_DEDENT; diff --git a/src/scanner.hpp b/src/scanner.hpp index f86630d..72092e3 100644 --- a/src/scanner.hpp +++ b/src/scanner.hpp @@ -5,18 +5,18 @@ #endif #include "parser.hpp" -#include "indent_helper.hpp" +#include "indent_stack.hpp" #include class Scanner : public yyFlexLexer { public: - IndentHelper indent_helper; + IndentStack indent_stack; Scanner(std::istream &in) : yyFlexLexer(&in), yylval(nullptr) {} int lex(yy::parser::semantic_type *lval) { - if (indent_helper.consumeDedent()) + if (indent_stack.popDedent()) { return yy::parser::token::TOK_DEDENT; } @@ -25,7 +25,9 @@ public: if (token == yy::parser::token::TOK_EOF) { - if (indent_helper.processLine(0) == IndentAction::Dedent) + auto result = indent_stack.closeBlock(); + + if (result == IndentAction::Dedent) { return yy::parser::token::TOK_DEDENT; }