mirror of
https://github.com/TomHarte/CLK.git
synced 2024-07-07 23:29:06 +00:00
Extended explicitly to support a token of lookahead, which is pretty much what was on offer anyway. Also corrected instance variable names, as per better adoption of C++ norms.
This commit is contained in:
parent
60300851ea
commit
4603fa6f24
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
namespace Storage {
|
namespace Storage {
|
||||||
namespace Tape {
|
namespace Tape {
|
||||||
@ -27,25 +28,37 @@ namespace Tape {
|
|||||||
template <typename WaveType, typename SymbolType> class Parser {
|
template <typename WaveType, typename SymbolType> class Parser {
|
||||||
public:
|
public:
|
||||||
/// Instantiates a new parser with the supplied @c tape.
|
/// Instantiates a new parser with the supplied @c tape.
|
||||||
Parser() : _has_next_symbol(false), _error_flag(false) {}
|
Parser() : has_next_symbol_(false), error_flag_(false) {}
|
||||||
|
|
||||||
/// Resets the error flag.
|
/// Resets the error flag.
|
||||||
void reset_error_flag() { _error_flag = false; }
|
void reset_error_flag() { error_flag_ = false; }
|
||||||
/// @returns @c true if an error has occurred since the error flag was last reset; @c false otherwise.
|
/// @returns @c true if an error has occurred since the error flag was last reset; @c false otherwise.
|
||||||
bool get_error_flag() { return _error_flag; }
|
bool get_error_flag() { return error_flag_; }
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Asks the parser to continue taking pulses from the tape until either the subclass next declares a symbol
|
Asks the parser to continue taking pulses from the tape until either the subclass next declares a symbol
|
||||||
or the tape runs out, returning the most-recently declared symbol.
|
or the tape runs out, returning the most-recently declared symbol.
|
||||||
*/
|
*/
|
||||||
SymbolType get_next_symbol(const std::shared_ptr<Storage::Tape::Tape> &tape) {
|
SymbolType get_next_symbol(const std::shared_ptr<Storage::Tape::Tape> &tape) {
|
||||||
while(!_has_next_symbol && !tape->is_at_end()) {
|
while(!has_next_symbol_ && !tape->is_at_end()) {
|
||||||
process_pulse(tape->get_next_pulse());
|
process_pulse(tape->get_next_pulse());
|
||||||
}
|
}
|
||||||
_has_next_symbol = false;
|
has_next_symbol_ = false;
|
||||||
return _next_symbol;
|
return next_symbol_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This class provides a single token of lookahead; return_symbol allows the single previous
|
||||||
|
token supplied by get_next_symbol to be returned, in which case it will be the thing returned
|
||||||
|
by the next call to get_next_symbol.
|
||||||
|
*/
|
||||||
|
void return_symbol(SymbolType symbol) {
|
||||||
|
assert(!has_next_symbol_);
|
||||||
|
has_next_symbol_ = true;
|
||||||
|
next_symbol_ = symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Should be implemented by subclasses. Consumes @c pulse. Is likely either to call @c push_wave
|
Should be implemented by subclasses. Consumes @c pulse. Is likely either to call @c push_wave
|
||||||
or to take no action.
|
or to take no action.
|
||||||
@ -60,8 +73,8 @@ template <typename WaveType, typename SymbolType> class Parser {
|
|||||||
Expected to be called by subclasses from @c process_pulse as and when recognised waves arise.
|
Expected to be called by subclasses from @c process_pulse as and when recognised waves arise.
|
||||||
*/
|
*/
|
||||||
void push_wave(WaveType wave) {
|
void push_wave(WaveType wave) {
|
||||||
_wave_queue.push_back(wave);
|
wave_queue_.push_back(wave);
|
||||||
inspect_waves(_wave_queue);
|
inspect_waves(wave_queue_);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -71,7 +84,7 @@ template <typename WaveType, typename SymbolType> class Parser {
|
|||||||
do not form a valid symbol.
|
do not form a valid symbol.
|
||||||
*/
|
*/
|
||||||
void remove_waves(int number_of_waves) {
|
void remove_waves(int number_of_waves) {
|
||||||
_wave_queue.erase(_wave_queue.begin(), _wave_queue.begin()+number_of_waves);
|
wave_queue_.erase(wave_queue_.begin(), wave_queue_.begin()+number_of_waves);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -81,17 +94,17 @@ template <typename WaveType, typename SymbolType> class Parser {
|
|||||||
waves together represent @c symbol.
|
waves together represent @c symbol.
|
||||||
*/
|
*/
|
||||||
void push_symbol(SymbolType symbol, int number_of_waves) {
|
void push_symbol(SymbolType symbol, int number_of_waves) {
|
||||||
_has_next_symbol = true;
|
has_next_symbol_ = true;
|
||||||
_next_symbol = symbol;
|
next_symbol_ = symbol;
|
||||||
remove_waves(number_of_waves);
|
remove_waves(number_of_waves);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_error_flag() {
|
void set_error_flag() {
|
||||||
_error_flag = true;
|
error_flag_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _error_flag;
|
bool error_flag_;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Should be implemented by subclasses. Inspects @c waves for a potential new symbol. If one is
|
Should be implemented by subclasses. Inspects @c waves for a potential new symbol. If one is
|
||||||
@ -101,9 +114,9 @@ template <typename WaveType, typename SymbolType> class Parser {
|
|||||||
*/
|
*/
|
||||||
virtual void inspect_waves(const std::vector<WaveType> &waves) = 0;
|
virtual void inspect_waves(const std::vector<WaveType> &waves) = 0;
|
||||||
|
|
||||||
std::vector<WaveType> _wave_queue;
|
std::vector<WaveType> wave_queue_;
|
||||||
SymbolType _next_symbol;
|
SymbolType next_symbol_;
|
||||||
bool _has_next_symbol;
|
bool has_next_symbol_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user