#ifndef _scan_h_
#define _scan_h_
#include <stdexcept>
#include <iostream>
#include <string>
#include "util.h"
using namespace std;
/*
* Token scanner object for the recursive descent parser. Breaks the input
* stream into the tokens described below, essentially identifiers, integer
* constants, and some operators.
*/
/* A token has a code number and the string it actually represents. */
class Scanner {
public:
/* These are code numbers for each token type. */
enum tok_code {
tok_id, // An identifier, L(L|D)*
tok_lit, // A literal: an unsigned integer number.
tok_left, // A left paren.
tok_right, // A right paren
tok_splat, // An asterisk
tok_slash, // A slash
tok_plus, // A plus sign
tok_minus, // A minus sign or dash
tok_asst, // An assignment symbol, :=
tok_semi, // A semicolon.
tok_EOF // END-of-file.
};
// The tokens returned by the scanner are of this type.
class Token: public ParserObject {
public:
tok_code code() const { return m_code; }
string text() const { return m_text; }
void pr(ostream &s, int indent) const {
s << spaces(indent) << m_codenames[m_code]
<< "(" << m_text << ")";
}
Token(): m_code(tok_EOF), m_text("Uninitialized") { }
Token(tok_code c, string t): m_code(c), m_text(t) { }
private:
tok_code m_code;
string m_text;
};
/* Get the current token. */
const Token & curr_tok() const { return m_curr; }
/* Move forward one token, and return the new current token. */
const Token & next_tok();
/* Create the scanner. Remembers the stream, and reads the
first token from it, which can be recovered with curr_token(). */
Scanner(istream &strm): m_in(strm) { next_tok(); }
private:
/* Reference to the underlying input stream. */
istream &m_in;
/* Current token. */
Token m_curr;
/* String names to correspond to the token codes */
static const char *m_codenames[];
};
// Class for scanner execeptions.
class BadInputCharacter: public runtime_error {
public:
BadInputCharacter(char ch):
runtime_error("Bad input character '" + ch_to_str(ch) + "'") { }
private:
string ch_to_str(char ch) {
char ret[2] = { ch, 0 };
return ret;
}
};
#endif