Go to the documentation of this file.
38 : mtasklist (tasklist), mcfile (controlfile), mcfile_version (1), verbosity (rverbosity)
76 <<
"Mixing positional and named arguments is not allowed.";
88 named_args.push_back(current_argument);
101 Index bracket_level = 0;
102 bool inside_quotes =
false;
107 while ((bracket_level || inside_quotes)
113 case '[': bracket_level++;
break;
116 if (bracket_level < 0)
123 if (prev_char !=
'\\')
124 inside_quotes = !inside_quotes;
134 throw ParseError(
"Unexpectedly reached end of file.\nProbably a runaway argument.",
175 os <<
"Expected ',' or ')' but found '" <<
msource.
Current() <<
"' after " << argname;
192 for (arg_index = 0; arg_index < (
Index)named_args.size(); arg_index++)
194 if (named_args[(
size_t)arg_index].name == name)
228 out3 <<
"\nParsing control text:\n";
236 if (
"Arts" !=
md_data[
id].Name() &&
"Arts2" !=
md_data[
id].Name() )
239 os <<
"The outermost agenda must be Arts2!\n"
240 <<
"(But it seems to be " <<
md_data[id].Name() <<
".)\n";
241 throw runtime_error(os.str());
259 os <<
"Unexpected character(s) at the end of the control file\n";
260 os <<
"after the main agenda was already closed.\n";
261 os <<
"File: " << x.
file() <<
'\n';
262 os <<
"Line: " << x.
line() <<
'\n';
263 os <<
"Column: " << x.
column() <<
'\n';
264 throw runtime_error(os.str());
271 os <<
"Unexpected end of control script.\n";
272 os <<
"File: " << x.
file() <<
'\n';
273 os <<
"Line: " << x.
line() <<
'\n';
274 throw runtime_error(os.str());
280 os <<
"Unexpected character:\n";
281 os << x.what() <<
'\n';
282 os <<
"File: " << x.
file() <<
'\n';
283 os <<
"Line: " << x.
line() <<
'\n';
284 os <<
"Column: " << x.
column() <<
'\n';
285 throw runtime_error(os.str());
291 os <<
"Illegal Line break:\n";
292 os << x.what() <<
'\n';
293 os <<
"File: " << x.
file() <<
'\n';
294 os <<
"Line: " << x.
line() <<
'\n';
295 throw runtime_error(os.str());
303 os <<
"Unknown Method:\n";
304 os << x.what() <<
'\n';
305 os <<
"File: " << x.
file() <<
'\n';
306 os <<
"Line: " << x.
line() <<
'\n';
307 os <<
"Column: " << x.
column() <<
'\n';
308 throw runtime_error(os.str());
316 os <<
"Unknown workspace variable:\n";
317 os << x.what() <<
'\n';
318 os <<
"File: " << x.
file() <<
'\n';
319 os <<
"Line: " << x.
line() <<
'\n';
320 os <<
"Column: " << x.
column() <<
'\n';
321 throw runtime_error(os.str());
327 os <<
"Attempt to create a workspace variable that already exists:\n";
328 os << x.what() <<
'\n';
329 os <<
"File: " << x.
file() <<
'\n';
330 os <<
"Line: " << x.
line() <<
'\n';
331 os <<
"Column: " << x.
column() <<
'\n';
332 throw runtime_error(os.str());
340 os <<
"Workspace variable belongs to the wrong group:\n";
341 os << x.what() <<
'\n';
342 os <<
"File: " << x.
file() <<
'\n';
343 os <<
"Line: " << x.
line() <<
'\n';
344 os <<
"Column: " << x.
column() <<
'\n';
345 throw runtime_error(os.str());
351 os <<
"Parse error:\n";
352 os << x.what() <<
'\n';
353 os <<
"File: " << x.
file() <<
'\n';
354 os <<
"Line: " << x.
line() <<
'\n';
355 os <<
"Column: " << x.
column() <<
'\n';
356 throw runtime_error(os.str());
400 auto_vars,auto_vars_values,include_file);
412 if (includedir.
nelem())
414 if (current_includepath.
nelem() && current_includepath[0] != includedir)
415 current_includepath.insert(current_includepath.begin(), includedir);
421 find_file (matching_files, include_file, current_includepath);
422 find_file (matching_files, include_file +
".arts", current_includepath);
424 if (!matching_files.
nelem())
427 os <<
"Cannot find include file " << include_file
430 os <<
"Search path was: " << current_includepath
432 throw runtime_error (os.str());
435 include_file = matching_files[0];
436 out2 <<
"- Including control file " << include_file <<
"\n";
450 auto_vars_values[0],tasks));
468 if (mname.length() > 6 &&
469 mname.find (
"Create") == mname.length() - 6 &&
475 map<String, Index>::const_iterator mdit;
476 mdit =
MdMap.find(method_name);
477 assert ( mdit !=
MdMap.end() );
487 out3 <<
"- " <<
md_data[id].Name() <<
"\n";
490 if ( 0 <
md_data[
id].GOutType().nelem()
491 +
md_data[
id].GInType().nelem() )
563 bool found_curly_brace =
false;
570 auto_vars.resize( 0 );
571 auto_vars_values.resize( 0 );
576 if (methodname ==
"INCLUDE")
587 if (methodname ==
"Arts2")
591 else if (methodname ==
"Arts")
593 throw runtime_error(
"Arts version 1 controlfiles are no longer supported.");
599 auto_vars, auto_vars_values);
608 found_curly_brace =
true;
616 out3 <<
"- " << mdd->
Name() <<
"\n";
626 os <<
"Expected method name , but got `" <<
msource.
Current() <<
"'.";
637 if (found_curly_brace)
646 if (!no_eot)
throw Eot(x);
687 istringstream is(mdd->
GInDefault()[gin_index]);
690 if (is.bad () || is.fail ())
696 istringstream is(mdd->
GInDefault()[gin_index]);
699 if (is.bad () || is.fail ())
727 <<
"Default values for generic inputs with type "
729 <<
"Either remove the default value for generic input '"
730 << mdd->
GIn()[gin_index] <<
"' in workspace method\n"
731 <<
"*" << mdd->
Name() <<
"* in methods.cc or discuss this "
732 <<
"issue on the arts-dev mailing list.\n";
745 name =
"auto_" + mdd->
Name() +
"_" +
"gin" + os.str() +
"_"
746 + mdd->
GIn()[gin_index];
749 map<String, Index>::const_iterator wsvit =
754 "Automatically allocated variable.",
760 wsvid = wsvit->second;
763 auto_vars.push_back(wsvid);
764 auto_vars_values.push_back(tv);
769 os <<
"Failed to assign default value for generic '"
770 << mdd->
GIn()[gin_index] <<
"'.\n"
771 <<
"Check the documentation of workspace method *"
772 << mdd->
Name() <<
"*.\n";
782 os <<
"Generic input '" << mdd->
GIn()[gin_index]
783 <<
"' omitted but no default value found.\n"
784 <<
"Check the documentation of workspace method *"
785 << mdd->
Name() <<
"*.\n";
823 bool still_supergeneric=
true;
828 const map<String, Index>::const_iterator md_raw_id =
MdRawMap.find(methodname);
835 id = md_raw_id->second;
847 const map<String, Index>::const_iterator i2 =
MdMap.find(methodname);
848 assert ( i2 !=
MdMap.end() );
853 still_supergeneric =
false;
859 Index supergeneric_index = -1;
861 Index this_method_end_line = -1;
862 Index this_method_end_column = -1;
863 bool call_by_name =
false;
896 bool is_first_arg =
true;
900 is_first_arg, still_supergeneric, supergeneric_args,
901 supergeneric_index, named_arguments, call_by_name);
904 named_arguments, call_by_name);
907 auto_vars, auto_vars_values,
908 is_first_arg, still_supergeneric, supergeneric_args,
909 supergeneric_index, named_arguments, call_by_name);
918 if (call_by_name && named_arguments.size())
922 os <<
"Too many arguments passed to " << mdd->
Name() <<
": ";
924 for (
size_t i = 0; i < named_arguments.size(); i++)
926 if (!first) os <<
", ";
928 os << named_arguments[i].name;
936 assert(!still_supergeneric);
944 os <<
"This method has generic output. "
945 <<
"You have to pass a variable!";
955 for (ArrayOfIndex::const_iterator outs=vo.begin();
956 outs<vo.end(); ++outs)
958 output.push_back (*outs);
962 for (ArrayOfIndex::const_iterator ins=vi.begin(); ins<vi.end(); ++ins)
964 input.push_back (*ins);
970 bool all_gin_have_defaults =
true;
972 all_gin_have_defaults && gin < mdd->
GIn().nelem();
979 all_gin_have_defaults =
false;
984 auto_vars_values, gin);
987 const map<String, Index>::const_iterator wsvit =
997 wsvid = wsvit->second;
999 input.push_back(wsvid);
1003 if (!all_gin_have_defaults)
1006 os <<
"Not all generic inputs of this method have default "
1007 <<
"values, you have to specify them!";
1041 bool& still_supergeneric,
1042 String& supergeneric_args,
1056 Index this_arg_index = 0;
1062 if (this_arg_index != -1)
1065 named_args[this_arg_index].column);
1066 named_args.erase(named_args.begin()+this_arg_index);
1084 if ((call_by_name && this_arg_index == -1)
1094 "generic" + os.str(),
1101 "Mixing positional and named arguments is not allowed.",
1106 throw ParseError(
"Only constants can be passed to Set methods.\n"
1107 "You might want to use the *Copy* here.",
1117 const map<String, Index>::const_iterator wsvit =
1127 wsvid = wsvit->second;
1133 if ( still_supergeneric )
1137 supergeneric_args +=
1139 os << mdd->
Name() <<
"_sg_" << supergeneric_args;
1140 methodname = os.str();
1143 const map<String, Index>::const_iterator mdit =
1144 MdMap.find(methodname);
1145 if (mdit !=
MdMap.end())
1151 still_supergeneric =
false;
1163 if (supergeneric_index == -1)
1165 bool wrong_group_id =
true;
1166 for (
Index i = 0; wrong_group_id && i < mdd->
GInSpecType()[j].nelem(); i++)
1171 wrong_group_id =
false;
1172 supergeneric_index = i;
1179 bool firsttype =
true;
1182 if (!firsttype) os <<
", ";
else firsttype =
false;
1188 +
" input. Check the online docs.",
1220 input.push_back(wsvid);
1247 bool& still_supergeneric,
1248 String& supergeneric_args,
1249 Index& supergeneric_index,
1260 for (
Index j=0 ; j<mdd->
GOut().nelem() ; ++j )
1264 Index this_arg_index;
1268 if (this_arg_index == -1)
1271 os <<
"This method has generic output. "
1272 <<
"You have to pass a variable!";
1280 named_args[this_arg_index].column);
1281 named_args.erase(named_args.begin()+this_arg_index);
1300 map<String, Index>::const_iterator wsvit =
1304 if (still_supergeneric)
1307 os <<
"This might be either a typo or you have to create "
1308 <<
"the variable\nby calling TYPECreate(" << wsvname
1309 <<
") first. Replace TYPE with the\n"
1310 <<
"WSV group your variable should belong to.";
1319 if (mdd->
Name().length() <= 6
1320 || mdd->
Name().substr(mdd->
Name().length() - 6) !=
"Create")
1323 os <<
"This might be either a typo or you have to create "
1324 <<
"the variable\nby calling "
1326 <<
"Create( " << wsvname
1337 "Automatically allocated variable.",
1346 if (mdd->
Name().length() > 6 &&
1347 mdd->
Name().find (
"Create") == mdd->
Name().length() - 6)
1350 os << wsvname <<
" already exists. A variable can only be created once.\n";
1356 wsvid = wsvit->second;
1364 if ( still_supergeneric )
1368 supergeneric_args +=
1370 os << mdd->
Name() <<
"_sg_" << supergeneric_args;
1371 methodname = os.str();
1374 const map<String, Index>::const_iterator mdit =
MdMap.find(methodname);
1375 if (mdit !=
MdMap.end() )
1381 still_supergeneric =
false;
1393 if (supergeneric_index == -1)
1395 bool wrong_group_id =
true;
1401 wrong_group_id =
false;
1402 supergeneric_index = i;
1409 bool firsttype =
true;
1412 if (!firsttype) os <<
", ";
else firsttype =
false;
1418 +
" output. Check the online docs.",
1451 output.push_back(wsvid);
1487 for (ArrayOfIndex::const_iterator ins=vi.begin(); ins<vi.end(); ++ins)
1493 Index this_arg_index;
1499 if (this_arg_index != -1)
1502 named_args[this_arg_index].column);
1503 named_args.erase(named_args.begin()+this_arg_index);
1537 const map<String, Index>::const_iterator wsvit =
1545 wsvid = wsvit->second;
1559 input.push_back(wsvid);
1589 for (ArrayOfIndex::const_iterator outs=vo.begin(); outs<vo.end(); ++outs)
1595 Index this_arg_index=0;
1602 if (this_arg_index != -1)
1605 named_args[this_arg_index].column);
1606 named_args.erase(named_args.begin()+this_arg_index);
1640 map<String, Index>::const_iterator wsvit =
1644 if (mdd->
Name().length() > 6
1645 && mdd->
Name().substr (mdd->
Name().length() - 6)
1649 os <<
"This might be either a typo or you have to create "
1650 <<
"the variable\nby calling "
1652 <<
"Create( " << wsvname
1663 "Automatically allocated variable.",
1670 wsvid = wsvit->second;
1685 output.push_back(wsvid);
1707 const Index method_type,
1715 map<String, Index>::const_iterator mdit;
1717 TokVal auto_keyword_value;
1734 <<
" constant to a WSM is not supported!";
1742 switch (method_type)
1745 auto_keyword_value = auto_vars_values[i];
1746 auto_output_var.push_back(auto_vars[i]);
1750 auto_input_var.push_back(auto_vars[i]);
1754 throw runtime_error(
"Invalid method_type");
1757 mdit =
MdMap.find(method_name);
1758 assert ( mdit !=
MdMap.end() );
1759 init_mdid = mdit->second;
1762 auto_output_var, auto_input_var,
1823 os <<
"Expected whitespace, but got `" << dummy <<
"'.";
1866 os <<
"Workspace variable names must start with a letter!";
1877 if ( isalnum(dummy) ||
'_'==dummy )
1915 const String& default_name,
1930 os <<
"Passing constants as supergeneric arguments is not supported.";
1943 name =
"auto_" + mdd->
Name() +
"_" + default_name;
1948 "Automatically allocated variable.",
1954 wsvid = wsvit->second;
1957 auto_vars.push_back(wsvid);
1965 auto_vars_values.push_back(dummy);
1971 auto_vars_values.push_back(n);
1977 auto_vars_values.push_back(n);
1983 auto_vars_values.push_back(dummy);
1989 auto_vars_values.push_back(dummy);
1995 auto_vars_values.push_back(dummy);
2001 auto_vars_values.push_back(dummy);
2029 os <<
"Expected '" << c <<
"', but got '" <<
msource.
Current() <<
"'.";
2106 if (
'+' == dummy ||
'-' == dummy )
2120 os <<
"Expected digit or variable name, but got `" <<
msource.
Current()
2131 if ( isdigit(chtmp) )
2168 bool found_digit =
false;
2172 if (
'+' == dummy ||
'-' == dummy )
2188 if ( isdigit(chtmp) )
2228 if ( isdigit(chtmp) )
2244 throw ParseError(
"Expected at least one digit.",
2251 if (
'e' == dummy ||
'E' == dummy )
2279 istringstream is(res);
2292 istringstream is(res);
2337 res.push_back(dummy);
2382 res.push_back(dummy);
2431 tres.push_back(dummy);
2437 for (
int i = 0; i < tres.
nelem (); i++)
2473 Index cur_ncols = 1;
2487 if (ncols != -1 && cur_ncols > ncols)
2490 os <<
"Expected ';', but got '" <<
msource.
Current() <<
"'. Check Matrix dimensions.";
2505 else if (ncols != cur_ncols)
2508 os <<
"Expected ',', but got '" <<
msource.
Current() <<
"'. Check Matrix dimensions.";
2521 if (ncols > cur_ncols)
2524 os <<
"Expected '" << c <<
"', but got '" <<
msource.
Current() <<
"'. Check Matrix dimensions.";
2533 tres.push_back(dummy);
2537 if (ncols == -1) ncols = cur_ncols;
2538 if (ncols != cur_ncols)
2540 throw ParseError(
"Missing element(s) in last row of matrix",
2549 res.
resize(nrows, ncols);
2550 for (
Index i = 0; i < nrows; i++)
2551 for (
Index j = 0; j < ncols; j++)
2552 res(i, j) = tres[i*ncols+j];
2577 if (str[pos] !=
'[')
2579 throw runtime_error (
"No opening bracket\n");
2588 while ( pos < str.length() && str[pos] !=
']' )
2594 if (str[pos] !=
',')
2603 istringstream is (str.substr(pos));
2605 if (is.bad () || is.fail ())
2607 tres.push_back(dummy);
2608 while (pos < str.length()
2609 && (isdigit(str[pos]) || str[pos] ==
'-' || str[pos] ==
'.'
2610 || str[pos] ==
'e'))
2617 for (
int i = 0; i < tres.
nelem (); i++)
2646 if (str[pos] !=
'[')
2648 throw runtime_error (
"No opening bracket\n");
2657 while ( pos < str.length() && str[pos] !=
']' )
2663 if (str[pos] !=
',')
2671 if (str[pos] !=
'"')
2673 throw runtime_error (
"Expected quotes\n");
2679 while ( pos < str.length() && str[pos] !=
'"' )
2685 if (pos == str.length() || str[pos] !=
'"')
2688 tres.push_back(dummy);
2694 res.resize(tres.
nelem());
2695 for (
int i = 0; i < tres.
nelem (); i++)
const ArrayOfString & GOut() const
static Array< WsvRecord > wsv_data
bool Supergeneric() const
const ArrayOfArrayOfIndex & GOutSpecType() const
void AppendFile(const String &name)
Appends contents of file to the source text.
const ArrayOfIndex & GOutType() const
void push_back(const MRecord &n)
Append a new method to end of list.
The declarations of all the exception classes.
void eat_whitespace_from_string(String &str, size_t &pos)
Eats whitespace from a String.
void parse_method(Index &id, ArrayOfIndex &output, ArrayOfIndex &input, Agenda &tasks, ArrayOfIndex &auto_vars, Array< TokVal > &auto_vars_values, String &include_file, bool no_eot=false)
Parse the Contents of text as ARTS control input.
void Init()
This sets the pointer to the first existing character in the text.
This stores arbitrary token values and remembers the type.
void read_integer(String &res)
Reads an integer.
void SetPosition(Index line, Index column)
Set current position.
const ArrayOfIndex & GInType() const
bool is_whitespace(const char c)
Returns true if this character is considered whitespace.
Structure to hold all command line Parameters.
const Array< MdRecord > md_data_raw
Lookup information for workspace methods.
Index nelem() const
Return the number of agenda elements.
Index ColumnRaw()
Return the column index.
void eat_whitespace()
Eats whitespace.
const map< String, Index > MdRawMap
The map associated with md_data_raw.
bool & LineBreak()
Read the line break flag.
void parse_matrix(Matrix &res)
Read a Matrix.
void resize(Index n)
Resize function.
void read_name(String &name)
Reads name of method, keyword, or workspace variable.
void parse_generic_output(const MdRecord *&mdd, Index &id, String &methodname, ArrayOfIndex &output, bool &first, bool &still_supergeneric, String &supergeneric_args, Index &supergeneric_index, NamedArguments &named_args, bool call_by_name)
Parse the generic output WSVs for current method from the controlfile.
void get_dirname(String &dirname, const String &path)
Return the parent directory of a path.
bool reachedEot()
Check if the current position reached the end.
void assertain_character(char c)
Make sure that the current character is equal to c and go to the next character.
Index LineRaw()
Return the line index.
void parse_intvector(ArrayOfIndex &res)
Read a vector of integers.
virtual String file() const
virtual Index column() const
Index Line()
Return the line number, but for the file that is associated with the current position.
const Verbosity & verbosity
void at_end_of_argument(const String &argname)
Check if current position in controlfile is at the end of an argument.
void find_named_arguments(vector< NamedArgument > &named_args)
Find named arguments.
String set_gin_to_default(const MdRecord *mdd, ArrayOfIndex &auto_vars, Array< TokVal > &auto_vars_values, Index keyword_index)
Set generic input to default value.
void get_argument_index_by_name(Index &arg_index, NamedArguments &named_args, String name)
Return the index of the argument with the given name.
void AdvanceLine()
Advances position pointer by one line.
virtual Index line() const
Index Column()
Return the current column.
bool parse_numvector_from_string(Vector &res, String &str)
Read a vector of Numerics from a String.
void parse_Stringvector(ArrayOfString &res)
Read a vector of Strings.
bool parse_stringarray_from_string(ArrayOfString &res, String &str)
Read an Array of Strings from a String.
void parse_agenda(Agenda &tasklist)
Parse the Contents of text as ARTS control input.
void parse_method_args(const MdRecord *&mdd, Index &id, String &methodname, ArrayOfIndex &output, ArrayOfIndex &input, ArrayOfIndex &auto_vars, Array< TokVal > &auto_vars_values)
Parse method's argument list.
void parse_specific_output(const MdRecord *mdd, ArrayOfIndex &output, bool &first, NamedArguments &named_args, bool call_by_name)
Parse the output WSVs for current method from the controlfile.
const map< String, Index > MdMap
The map associated with md_data.
bool AgendaMethod() const
const String & File()
Return the filename associated with the current position.
void parse_tasklist()
Public interface to the main function of the parser.
NUMERIC Numeric
The type to use for all floating point numbers.
const String & Name() const
void read_numeric(String &res)
Reads a floating point number.
void resize(Index r, Index c)
Resize function.
const ArrayOfIndex & InOnly() const
This file contains header information for the dealing with command line parameters.
Index nelem() const
Number of elements.
const Array< String > & GInDefault() const
const Array< MdRecord > md_data
Lookup information for workspace methods.
Index read_name_or_value(String &name, ArrayOfIndex &auto_vars, Array< TokVal > &auto_vars_values, const String &default_name, const MdRecord *mdd, const Index group)
Reads name of a workspace variable or a value.
ArtsParser(Agenda &tasklist, String controlfile, const Verbosity &verbosity)
Constructs a new parser.
const ArrayOfString & GIn() const
This class contains all static information for one workspace variable.
This file contains the declaration and partly the implementation of the workspace class.
All information for one workspace method.
Parameters parameters
Holds the command line parameters.
static map< String, Index > WsvMap
char Current()
Return the current character.
void parse_numeric(Numeric &n)
Use a String stream to parse a floating point number.
const ArrayOfArrayOfIndex & GInSpecType() const
static Index add_wsv(const WsvRecord &wsv)
void parse_main()
The main function of the parser.
void resize(Index n)
Resize the method list.
void parse_numvector(Vector &res)
Read a vector of Numerics.
void parse_integer(Index &n)
Use a String stream to parse an integer number.
This file contains basic functions to handle ASCII files.
void parse_generic_input(const MdRecord *&mdd, Index &id, String &methodname, ArrayOfIndex &input, ArrayOfIndex &auto_vars, Array< TokVal > &auto_vars_values, bool &first, bool &still_supergeneric, String &supergeneric_args, Index &supergeneric_index, NamedArguments &named_args, bool call_by_name)
Parse the generic input WSVs for current method from the controlfile.
void parse_specific_input(const MdRecord *mdd, ArrayOfIndex &input, ArrayOfIndex &auto_vars, Array< TokVal > &auto_vars_values, bool &first, NamedArguments &named_args, bool call_by_name)
Parse the specific input WSVs for current method from the controlfile.
void AdvanceChar()
Advance position pointer by one character.
INDEX Index
The type to use for all integer numbers and indices.
const ArrayOfIndex & Out() const
const Array< MRecord > & Methods() const
const ArrayOfString wsv_group_names
The names associated with Wsv groups as Strings.
vector< NamedArgument > NamedArguments
ArrayOfString includepath
List of paths to search for include files.
void parse_String(String &res)
Reads a String, complete with quotation marks.
Index get_wsv_group_id(const String &name)
Returns the id of the given group.
void skip_to_next_argument()
Skips forward to the next argument.
ArrayOfString datapath
List of paths to search for data files.
Index nelem() const
Number of elements.
Declaration of the class MdRecord.
Auxiliary header stuff related to workspace variable groups.
The global header file for ARTS.
void tasklist_insert_set_delete(const ArrayOfIndex &auto_vars, const Array< TokVal > &auto_vars_values, const Index method_type, Agenda &tasklist)
Insert Set and Delete methods for automatically allocated output WSVs.
bool find_file(ArrayOfString &matches, const String &filename, const ArrayOfString &paths, const ArrayOfString &extensions)
Searches through paths for a file with a matching name.