lexer.h 1.89 KB
Newer Older
Ronald Charles Moore's avatar
Ronald Charles Moore committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// This code made available to his students by 
// Prof. Ronald Moore  
//     https://fbi.h-da.de/personen/ronald-moore/  
//     mailto:ronald.moore@h-da.de
// with no warranties whatsoever!

#pragma once 

#include <cctype> // for isspace
#include <cstdlib> // for strtod
#include <string>
#include <cmath>  // for NAN
#include <utility> // for std::pair
#include <variant> // new C++17 feature! Like unions, only better!

// ===================
// LEXICAL ANALYSIS
// The following are taken to be tokens:
// left and right parenthesis, the plus and minus characters,
// as well as asterisk and forward slash -- and numbers.
// In the script, substraction and division are not supported,
// but it seems like time to add them.

// Preliminaries and Utilities
// ============================

namespace lex {
	
// Utility Types
Ronald Charles Moore's avatar
Ronald Charles Moore committed
30
typedef double numberType; // also works with (at least) float or long
Ronald Charles Moore's avatar
Ronald Charles Moore committed
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

// See https://en.cppreference.com/w/cpp/numeric/math/nan
static const numberType	bad_number = std::nan( "1" ); 

// Tokens -- are a pair of a tag and a value, where the value can be 
// various things - a char or a numberType at present, but names and 
// multicharacter operators could be added later
typedef enum { 
	tok_number = 'n',
	tok_lparen = '(',
	tok_rparen = ')',
	tok_plus   = '+',
	tok_minus  = '-',
	tok_times  = '*',
	tok_div    = '/',
	tok_eof    = 'E',
	bad_tok    = 'X'
} TokenTag;

typedef std::variant< char, numberType > TokenValue;

typedef std::pair< TokenTag, TokenValue > Token;

extern Token next_token; // again with the global variables... { 

// Functons (or methods, if you prefer)

void printInputLocation( );

void printErrorMsg( const std::string Error );

Token gettok( ); // 

// DRY -- this line is repeated so often, it deserves its own function
inline void advance_token( ) { next_token = gettok(); } // eats current token!

void openInputSource( std::string filename );

} // end namespace lex