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)) {
89 if (l == ci.length && s.substr(0, ci.length) == ci.word)
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.
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
this header is dependency free
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
unsigned int block_end
store the index of the command token that terminates the block following this command
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
token()
construct with both pointers set to 0