1#include "command_token.h"
4#include <cgv/utils/tokenizer.h>
11 std::string command_token::last_error;
12 token command_token::last_error_token;
20 unsigned min_nr_expressions;
21 unsigned nr_expressions;
23 bool remove_empty_before;
24 bool parse_expressions;
25 const char* open_parentheses;
26 const char* close_parentheses;
32 { CT_TEXT,
"text", 4, 4, 1, 1,
false,
true,
true,
"(",
")" },
33 { CT_DEFINE,
"define", 6, 6, 1, 1,
false,
true,
true,
"(",
")" },
34 { CT_SKIP,
"skip", 4, 4, 1, 1,
false,
true,
true,
"(",
")" },
35 { CT_READ,
"read", 4, 4, 3, 3,
false,
true,
true,
"(",
")" },
36 { CT_WRITE,
"write", 5, 5, 3, 3,
false,
true,
true,
"(",
")" },
37 { CT_RAND,
"rand", 4, 4, 3, 4,
false,
true,
true,
"(",
")" },
38 { CT_NAMESPACE,
"namespace", 9, 9, 1, 1,
true,
true,
true,
"(",
")" },
39 { CT_FOR,
"for", 3, 3, 3, 3,
true,
true,
true,
"(",
")" },
40 { CT_IF,
"if", 2, 2, 1, 1,
true,
true,
true,
"(",
")" },
41 { CT_ELIF,
"elif", 4, 4, 1, 1,
true,
true,
true,
"(",
")" },
42 { CT_ELSE,
"else", 4, 4, 0, 0,
true,
true,
true,
"",
"" },
43 { CT_EVAL,
"(", 1, 0, 1, 1,
false,
false,
true,
"(",
")" },
44 { CT_STRING,
"\"", 1, 0, 1, 1,
false,
false,
true,
"\"",
"\"" },
45 { CT_LIST,
"[", 1, 0, 3, 3,
false,
false,
true,
"[",
"]" },
46 { CT_BEGIN,
"{", 1, 1, 0, 0,
false,
true,
true,
"",
"" },
47 { CT_END,
"}", 1, 1, 0, 0,
false,
true,
true,
"",
"" },
48 { CT_INCLUDE,
"include", 7, 7, 1, 1,
false,
true,
false,
"<\"(",
">\")" },
49 { CT_CINCLUDE,
"#include", 8, 8, 1, 1,
false,
true,
false,
"<\"(",
">\")" },
50 { CT_EXCLUDE,
"exclude", 7, 7, 1, 1,
false,
true,
false,
"<\"(",
">\")" },
51 { CT_INSERT,
"insert", 6, 6, 1, 1,
false,
true,
false,
"<\"(",
">\")" },
52 { CT_REFLECT_NEXT_LINE,
">", 1, 1, 0, 0,
false,
false,
false,
"",
"" },
53 { CT_REFLECT_PREV_LINE,
"<", 1, 1, 0, 0,
false,
false,
false,
"",
"" },
54 { CT_COUT,
"cout", 4, 4, 1, 1,
false,
true,
true,
"(",
")" },
55 { CT_CIN,
"cin", 3, 3, 1, 1,
false,
true,
true,
"(",
")" },
56 { CT_ERROR,
"error", 5, 5, 2, 2,
false,
true,
true,
"(",
")" },
57 { CT_WARNING,
"warning", 7, 7, 2, 2,
false,
true,
true,
"(",
")" },
58 { CT_SYSTEM,
"system", 6, 6, 2, 2,
false,
true,
true,
"(",
")" },
59 { CT_DIR,
"dir", 3, 3, 4, 4,
false,
true,
true,
"(",
")" },
60 { CT_FUNC,
"func", 4, 4, 1, 2,
true,
true,
true,
"(",
")" },
61 { CT_EXIT,
"exit", 4, 4, 1, 1,
false,
true,
true,
"(",
")" },
62 { CT_TRANSFORM,
"transform", 9, 9, 2, 2,
false,
true,
true,
"(",
")" },
63 { CT_SCAN_INCLUDES,
"scan_includes", 13, 13, 2, 2,
false,
true,
true,
"(",
")" },
68 const char* get_command_word(CommandType ct)
71 case CT_IMPLICIT_TEXT:
return "text";
72 case CT_UNDEF:
return "undef";
73 default:
return get_command_info(ct).word;
78 CommandType determine_command_type(
const std::string& s)
82 while (l < s.size() && (
is_digit(s[l]) || is_letter(s[l]) || s[l] ==
'#' || s[l] ==
'_'))
87 for (CommandType ct = (CommandType)0; ct < CT_UNDEF; ct =
CommandType(ct + 1)) {
88 const command_info& ci = get_command_info(ct);
89 if (l == ci.length && s.substr(0, ci.length) == ci.word)
96 : ct(CT_UNDEF), parenthesis_index(0), block_end(0)
101 :
token(t), ct(CT_IMPLICIT_TEXT), parenthesis_index(0), block_end(0)
108 return get_command_info(
ct).skip_length;
114 return get_command_info(
ct).nr_expressions;
120 return get_command_info(
ct).min_nr_expressions;
133 return get_command_info(
ct).word;
139 if (
ct != CT_IMPLICIT_TEXT)
147 unsigned int nr_lines = 0;
148 for (
const char* p =
begin; p < end; ++p)
160 if (
ct == CT_IMPLICIT_TEXT ||
ct == CT_UNDEF)
162 return get_command_info(
ct).block_follows;
168 if (
ct == CT_IMPLICIT_TEXT ||
ct == CT_UNDEF)
170 return get_command_info(
ct).remove_empty_before;
190 ct = determine_command_type(s);
191 if (
ct == CT_UNDEF) {
192 last_error =
"could not determine command";
193 last_error_token = t;
204 const std::string& open_ps = get_command_info(
ct).open_parentheses;
205 const std::string& close_ps = get_command_info(
ct).close_parentheses;
208 if (
tokenizer(t).set_skip(
"'\"",
"'\"").balanced_bite(exp_tok, open_ps, close_ps)) {
210 last_error =
"enclosing parenthesis not valid";
211 last_error_token = *
this;
214 t.
begin = exp_tok.end;
218 std::vector<token> expr_tokens;
220 if (expr_tokens.size() > ne || expr_tokens.size() < mne) {
221 last_error =
"found " +
to_string(expr_tokens.size()) +
" expressions, but " +
get_keyword() +
" allows ";
223 last_error +=
"only " +
to_string(ne) +
" expressions";
226 last_error_token = *
this;
230 for (
unsigned int i = 0; i < expr_tokens.size(); ++i) {
232 if (!ep.parse(expr_tokens[i])) {
233 last_error =
"parse error in expression ";
235 last_error_token = expr_tokens[i];
238 bool allow_several_values =
false;
239 if (
ct == CT_FUNC && i == 1)
240 allow_several_values =
true;
241 if (!ep.
validate(allow_several_values)) {
242 last_error =
"could not validate expression ";
244 last_error += ep.get_last_error() +
")";
245 if (ep.get_last_error_token().
empty())
246 last_error_token = expr_tokens[i];
248 last_error_token = ep.get_last_error_token();
260 last_error =
"could not find parenthesis enclosing expressions";
261 last_error_token = t;
265 const std::string& command_token::get_last_error()
269 const token& command_token::get_last_error_token()
271 return last_error_token;
bool validate(bool allow_several_values=false)
the tokenizer allows to split text into tokens in a convenient way.
Helper functions to convert numeric types into strings using std streams.
CommandType
enumerate type for all command types supported in configuration files
namespace that holds tools that dont fit any other namespace
bool is_digit(char c)
check if char is a digit
std::string to_string(const std::string &v, unsigned int w, unsigned int p, bool)
specialization of conversion from string to strings
void bite_all(tokenizer &t, std::vector< token > &result)
bite all tokens into a token vector
bool is_element(char c, const std::string &s)
check if char c arises in string s
const char * skip_spaces(const char *begin, const char *end)
return new start pointer by skipping spaces at begin
Helper functions to process strings.
unsigned get_skip_length() const
get the number of characters to be skipped before expressions start
bool is_nr_expressions_fix() const
return whether the number of expressions that the command takes as argument is fix
char get_close_parenthesis() const
return the close parenthesis enclosing the expressions
bool remove_preceeding_empty_text_token() const
return whether empty text tokens before this command token should be deleted
char get_open_parenthesis() const
return the open parenthesis enclosing the expressions
unsigned get_nr_expressions() const
return the number of expressions that the command takes as argument
bool block_follows() const
return whether the command token must be followed by a block
const char * get_keyword() const
return the keyword describing the command
bool is_empty() const
check whether the token only contains white spaces
bool split_off_from(token &t)
splits a command token from the front of a given token
command_token()
constructs an undefined command token
unsigned int parenthesis_index
store index of parenthesis that enclosed the expressions
CommandType ct
store command type
std::vector< expression_processor > expressions
vector of parsed expressions
unsigned get_min_nr_expressions() const
return the minimum number of expressions that the command takes as argument
representation of a token in a text by two pointers begin and end, that point to the first character ...
bool empty() const
return whether the token is empty
const char * begin
pointers that define the range of characters