summaryrefslogtreecommitdiffstats
path: root/pigeonhole/src/lib-sieve/sieve-lexer.h
blob: 95451cc9bd346b57a7b1ce7900f05bf3bdcf09b3 (plain)
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
30
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#ifndef SIEVE_LEXER_H
#define SIEVE_LEXER_H

#include "lib.h"
#include "str.h"

#include "sieve-common.h"

enum sieve_token_type {
	STT_NONE,
	STT_WHITESPACE,
	STT_EOF,

	STT_NUMBER,
	STT_IDENTIFIER,
	STT_TAG,
	STT_STRING,

	STT_RBRACKET,
	STT_LBRACKET,
	STT_RCURLY,
	STT_LCURLY,
	STT_RSQUARE,
	STT_LSQUARE,
	STT_SEMICOLON,
	STT_COMMA,

	/* These are currently not used in the lexical specification, but a
	   token is assigned to these to generate proper error messages (these
	   are technically not garbage and possibly part of mistyped but
	   otherwise valid tokens).
	 */
	STT_SLASH,
	STT_COLON,

	/* Error tokens */
	STT_GARBAGE, /* Error reporting deferred to parser */
	STT_ERROR    /* Lexer is responsible for error, parser won't report
	                additional errors */
};

/*
 * Lexer object
 */

struct sieve_lexical_scanner;

struct sieve_lexer {
	struct sieve_lexical_scanner *scanner;

	enum sieve_token_type token_type;
	string_t *token_str_value;
	sieve_number_t token_int_value;

	int token_line;
};

const struct sieve_lexer *
sieve_lexer_create(struct sieve_script *script,
		   struct sieve_error_handler *ehandler,
		   enum sieve_error *error_r);
void sieve_lexer_free(const struct sieve_lexer **lexer);

/*
 * Scanning
 */

void sieve_lexer_skip_token(const struct sieve_lexer *lexer);

/*
 * Token access
 */

static inline enum sieve_token_type
sieve_lexer_token_type(const struct sieve_lexer *lexer)
{
	return lexer->token_type;
}

static inline const string_t *
sieve_lexer_token_str(const struct sieve_lexer *lexer)
{
	i_assert(lexer->token_type == STT_STRING);

	return lexer->token_str_value;
}

static inline const char *
sieve_lexer_token_ident(const struct sieve_lexer *lexer)
{
	i_assert(lexer->token_type == STT_TAG ||
		 lexer->token_type == STT_IDENTIFIER);

	return str_c(lexer->token_str_value);
}

static inline sieve_number_t
sieve_lexer_token_int(const struct sieve_lexer *lexer)
{
	i_assert(lexer->token_type == STT_NUMBER);

	return lexer->token_int_value;
}

static inline bool sieve_lexer_eof(const struct sieve_lexer *lexer)
{
	return lexer->token_type == STT_EOF;
}

static inline int sieve_lexer_token_line(const struct sieve_lexer *lexer)
{
	return lexer->token_line;
}

const char *sieve_lexer_token_description(const struct sieve_lexer *lexer);

void sieve_lexer_token_print(const struct sieve_lexer *lexer);

#endif