File: parser.h

package info (click to toggle)
teg 0.13.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 19,036 kB
  • sloc: cpp: 16,819; xml: 1,313; makefile: 268; sh: 195; ansic: 112
file content (168 lines) | stat: -rw-r--r-- 3,809 bytes parent folder | download
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/* Tenes Empanadas Graciela
 *
 * Copyright (C) 2000 Ricardo Quesada
 *
 * Author: Ricardo Calixto Quesada <rquesada@core-sdi.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; only version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 */
/*
 * Estructura del parser
 */

#pragma once

#include <cstddef>

#define PARSER_TOKEN_MAX 1024
#define PARSER_VALUE_MAX 1024

struct DELIM {
	char accept;
	bool valid=true;

	DELIM& operator = (DELIM const* other)
	{
		if(other) {
			*this = *other;
		} else {
			valid = false;
		}
		return *this;
	}
};

struct PARSER {
	PARSER(char const *data, char eq=':', char sep=',')
		: PARSER{data, DELIM{eq}, DELIM{sep}}
	{
	}

	PARSER(char const *data, DELIM const& eq, DELIM const& sep)
		: data{data}, equals{eq}, separators{sep}
		, m_can_continue{bool(data) && (data[0] != 0)}, m_ok{m_can_continue}
	{
	}

	void reset(char const* retry)
	{
		data = retry;
		m_can_continue = true;
		m_ok = true;
	}

	char const* remainder() const
	{
		return data;
	}

	/// Try to parse the input text, and return if it was successful
	bool parse();

	/// Parse with the expectation that there will something remain
	bool parse_fragment()
	{
		return parse() && can_continue();
	}

	/// parse with the expectation that everything is captured
	bool parse_everything()
	{
		return parse() && !can_continue();
	}

	/** \brief parses the next token
	 *
	 * This function checks if the parser is in a continuable state, and tries
	 * to fetch the next token from the input.
	 *
	 * The parser state will be set to failed when there is no more input to
	 * consume.
	 *
	 * \return true, if there where no previous errors, and one token could be
	 *         extracted. false otherwise. */
	bool parse_token()
	{
		if(ok()) {
			if(parse()) {
				return true;
			} else {
				fail();
			}
		}
		return false;
	}

	/** Returns the parser extraction state.
	 *
	 * The extraction operators can set the parser to failed when they recognize
	 * that the input string did not match the syntax. This property can be
	 * queried with this method. */
	bool ok() const
	{
		return m_ok;
	}

	bool can_continue()const
	{
		return bool(data) && m_can_continue;
	}

	/** Returns if the parsing steps where succesfull and there are no more
	 *  tokens left in the input */
	bool finished() const
	{
		return ok() && !can_continue();
	}

	/** \brief Set the indication that a value could not be parsed.
	 *
	 * This method is meant to be called by the `>>` parsing operators. */
	void fail()
	{
		m_ok=false;
	}

	char token[PARSER_TOKEN_MAX];
	char value[PARSER_VALUE_MAX];

private:
	DELIM const equals;
	DELIM const separators;
	char const *data;

	bool m_can_continue;
	bool m_ok;
};

PARSER& operator >> (PARSER& source, int& value);

struct Limited {
	int &dest; ///< Variable to set
	int const min; ///< minimal acceptable value
	int const max; ///< maximal acceptable value

	/// value to set if the syntax of the input is wrong or out of bounds
	int const reset_to;
};

PARSER& operator >> (PARSER& source, Limited && limit);

struct CString {
	template <std::size_t sz> CString(char (&dest)[sz]) : dest{dest}, count{sz} {}
	char *const dest;
	std::size_t const count;
};

PARSER& operator >> (PARSER& source, CString && limit);