ARTS  1.0.222
parser.cc
Go to the documentation of this file.
1 /* Copyright (C) 2000, 2001 Stefan Buehler <sbuehler@uni-bremen.de>
2 
3  This program is free software; you can redistribute it and/or modify it
4  under the terms of the GNU General Public License as published by the
5  Free Software Foundation; either version 2, or (at your option) any
6  later version.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16  USA. */
17 
18 #include "arts.h"
19 #include <map>
20 #include "messages.h"
21 #include "exceptions.h"
22 #include "file.h"
23 #include "auto_wsv.h"
24 #include "methods.h"
25 #include "parser.h"
26 #include "wsv_aux.h"
27 
28 void SourceText::AppendFile(const String& name)
29 {
30  mSfLine.push_back(mText.nelem());
31  mSfName.push_back(name);
32 
33  read_text_from_file(mText, name);
34 }
35 
37 {
38  if ( mColumn < mText[mLine].nelem()-1 )
39  {
40  ++mColumn;
41  }
42  else
43  {
44  mLineBreak = true;
45  do
46  {
47  if (mLine>=mText.nelem()-1)
48  {
49  throw Eot( "",
50  this->File(),
51  this->Line(),
52  this->Column() );
53  }
54  else
55  {
56  ++mLine;
57  mColumn = 0;
58  }
59  }
60  while ( 1 > mText[mLine].nelem() ); // Skip empty lines.
61  }
62 }
63 
64 
66 {
67  mLineBreak = true;
68  mColumn = 0;
69  do
70  {
71  if (mLine>=mText.nelem()-1)
72  {
73  throw Eot( "",
74  this->File(),
75  this->Line(),
76  this->Column() );
77  }
78  else
79  {
80  ++mLine;
81  }
82  }
83  while ( 1 > mText[mLine].nelem() ); // Skip empty lines.
84 }
85 
86 
88 {
89  Index i = 0;
90  bool stop = false;
91 
92  while ( i<mSfLine.nelem()-1 && !stop )
93  {
94  if (mLine>=mSfLine[i+1]) ++i;
95  else stop = true;
96  }
97 
98  return mSfName[i];
99 }
100 
101 
103 {
104  Index i = 0;
105  bool stop = false;
106 
107  while ( i<mSfLine.nelem()-1 && !stop )
108  {
109  if (mLine>=mSfLine[i+1]) ++i;
110  else stop = true;
111  }
112 
113  return mLine - mSfLine[i] + 1;
114 }
115 
116 
118 {
119  mLine = 0;
120  mColumn = 0;
121 
122  if ( 1 > mText.nelem() )
123  {
124  throw Eot( "Empty text!",
125  this->File(),
126  this->Line(),
127  this->Column() );
128  }
129  else
130  {
131  // Skip empty lines:
132  while ( 1 > mText[mLine].nelem() )
133  {
134  if (mLine>=mText.nelem()-1)
135  {
136  throw Eot( "",
137  this->File(),
138  this->Line(),
139  this->Column() );
140  }
141  else
142  {
143  mLineBreak = true;
144  ++mLine;
145  }
146  }
147  }
148 }
149 
150 
151 ostream& operator << (ostream& os, const SourceText& text)
152 {
153  for (Index i=0; i<text.mText.nelem();++i)
154  cout << i
155  << "(" << text.mText[i].nelem() << ")"
156  << ": " << text.mText[i] << '\n';
157  return(os);
158 }
159 
160 
168 bool is_whitespace(const char c)
169 {
170  switch (c)
171  {
172  case ' ':
173  case '\r':
174  case '\t':
175  case '#':
176  return true;
177  break;
178  default:
179  return false;
180  break;
181  }
182 }
183 
194 {
195  char dummy;
196 
197  while (is_whitespace(dummy=text.Current()))
198  {
199  switch (dummy)
200  {
201  case ' ':
202  case '\r':
203  case '\t':
204  text.AdvanceChar();
205  break;
206  case '#':
207  text.AdvanceLine();
208  break;
209  default:
210  {
211  ostringstream os;
212  os << "Expected whitespace, but got `" << dummy << "'.";
213  throw UnexpectedChar( os.str(),
214  text.File(),
215  text.Line(),
216  text.Column() );
217  break;
218  }
219  }
220  }
221 }
222 
223 
232 void read_name(String& name, SourceText& text)
233 {
234  bool stop = false;
235  name = "";
236 
237  while (!stop)
238  {
239  char dummy = text.Current();
240 
241  if ( isalnum(dummy) || '_'==dummy )
242  {
243  name += dummy;
244  // AdvanceChar sets LineBreak if a line break occured.
245  text.LineBreak() = false;
246  text.AdvanceChar();
247  if ( text.LineBreak() ) stop = true;
248  }
249  else
250  {
251  stop = true;
252  }
253  }
254 
255  // cout << "Name: " << name << '\n';
256 }
257 
262 void assertain_character(char c, SourceText& text)
263 {
264  if ( c != text.Current() )
265  {
266  ostringstream os;
267  os << "Expected `" << c << "', but got `" << text.Current() << "'.";
268  throw UnexpectedChar( os.str(),
269  text.File(),
270  text.Line(),
271  text.Column() );
272  }
273 
274  text.AdvanceChar();
275 }
276 
285 void parse_String(String& res, SourceText& text)
286 {
287  bool stop = false;
288  res = "";
289 
290  text.LineBreak() = false;
291  assertain_character('"',text);
292  if ( text.LineBreak() )
293  throw IllegalLinebreak( "Line break before end of String.",
294  text.File(),
295  text.Line(),
296  text.Column() );
297 
298  while (!stop)
299  {
300  char dummy = text.Current();
301  if ( dummy != '"' )
302  {
303  res += dummy;
304  text.AdvanceChar();
305 
306  if ( text.LineBreak() )
307  throw IllegalLinebreak( "Line break before end of String.",
308  text.File(),
309  text.Line(),
310  text.Column() );
311  }
312  else
313  {
314  stop = true;
315  text.AdvanceChar();
316  }
317  }
318 }
319 
330 void read_integer(String& res, SourceText& text)
331 {
332  bool stop = false;
333  res = "";
334  char dummy;
335  text.LineBreak() = false;
336 
337  dummy = text.Current();
338  if ( '+' == dummy || '-' == dummy )
339  {
340  res += dummy;
341  text.AdvanceChar();
342  if ( text.LineBreak() )
343  throw IllegalLinebreak( "Line break after sign.",
344  text.File(),
345  text.Line(),
346  text.Column() );
347  }
348 
349  if (!isdigit(text.Current()))
350  {
351  ostringstream os;
352  os << "Expected digit, but got `" << text.Current() << "'.";
353  throw UnexpectedChar(os.str(),
354  text.File(),
355  text.Line(),
356  text.Column());
357  }
358 
359  while (!stop)
360  {
361  char dummy = text.Current();
362  if ( isdigit(dummy) )
363  {
364  res += dummy;
365  text.AdvanceChar();
366  if ( text.LineBreak() ) stop = true;
367  }
368  else
369  {
370  stop = true;
371  }
372  }
373 }
374 
388 void read_numeric(String& res, SourceText& text)
389 {
390  bool stop;
391  res = "";
392  char dummy;
393  text.LineBreak() = false;
394 
395  // To make sure that there is at least one digit:
396  bool found_digit = false;
397 
398  // Check if there is a sign:
399  dummy = text.Current();
400  if ( '+' == dummy || '-' == dummy )
401  {
402  res += dummy;
403  text.AdvanceChar();
404  if ( text.LineBreak() )
405  throw IllegalLinebreak( "Linebreak after sign.",
406  text.File(),
407  text.Line(),
408  text.Column() );
409  }
410 
411  // There could be some digits here:
412  stop = false;
413  while (!stop)
414  {
415  char dummy = text.Current();
416  if ( isdigit(dummy) )
417  {
418  found_digit = true;
419  res += dummy;
420  text.AdvanceChar();
421  if ( text.LineBreak() ) return; // Line break ends scanning immediately.
422  }
423  else
424  {
425  stop = true;
426  }
427  }
428 
429  // Next there can be a decimal point
430  if ( '.' == text.Current() )
431  {
432  res += ".";
433  text.AdvanceChar();
434  if ( text.LineBreak() )
435  {
436  if (found_digit)
437  {
438  // Line break ends scanning immediately, if we have
439  // already found at least one digit.
440  return;
441  }
442  else
443  {
444  throw IllegalLinebreak("Expected at least one digit.",
445  text.File(),
446  text.Line(),
447  text.Column());
448  }
449  }
450 
451  // ... followed by optional more digits
452  stop = false;
453  while (!stop)
454  {
455  char dummy = text.Current();
456  if ( isdigit(dummy) )
457  {
458  found_digit = true;
459  res += dummy;
460  text.AdvanceChar();
461  if ( text.LineBreak() ) return; // Line break ends scanning immediately.
462  }
463  else
464  {
465  stop = true;
466  }
467  }
468  }
469 
470  // At this point, we must have found at least one digit.
471  if (!found_digit)
472  throw ParseError("Expected at least one digit.",
473  text.File(),
474  text.Line(),
475  text.Column());
476 
477  // Now there could be a `e' or `E':
478  dummy = text.Current();
479  if ( 'e' == dummy || 'E' == dummy )
480  {
481  res += dummy;
482  text.AdvanceChar();
483  if ( text.LineBreak() )
484  throw IllegalLinebreak( "Linebreak after e/E.",
485  text.File(),
486  text.Line(),
487  text.Column() );
488 
489  // Now there must be an integer (with optional sign)
490  {
491  String s;
492  read_integer(s,text);
493  res += s;
494  }
495  }
496 }
497 
500 {
501  String res;
502  read_integer(res, text);
503  istringstream is(res);
504  is >> n;
505 }
506 
509 {
510  String res;
511  read_numeric(res, text);
512  istringstream is(res);
513  is >> n;
514 }
515 
531 {
532  bool first = true; // To skip the first comma.
533  res.resize(0); // Clear the result vector (just in case).
534 
535  // Make sure that the current character really is `[' and proceed.
536  assertain_character('[',text);
537  // There might have occured a linebreak, which is fine.
538 
539  eat_whitespace(text);
540 
541  // Read the elements of the vector (`]' means that we have
542  // reached the end):
543  while ( ']' != text.Current() )
544  {
545  String dummy;
546 
547  if (first)
548  first = false;
549  else
550  {
551  assertain_character(',',text);
552  eat_whitespace(text);
553  }
554 
555  parse_String(dummy, text);
556  res.push_back(dummy);
557  eat_whitespace(text);
558  }
559 
560  text.AdvanceChar();
561 }
562 
575 {
576  bool first = true; // To skip the first comma.
577  res.resize(0); // Clear the result vector (just in case).
578 
579  // Make sure that the current character really is `[' and proceed.
580  assertain_character('[',text);
581  // There might have occured a linebreak, which is fine.
582 
583  eat_whitespace(text);
584 
585  // Read the elements of the vector (`]' means that we have
586  // reached the end):
587  while ( ']' != text.Current() )
588  {
589  Index dummy;
590 
591  if (first)
592  first = false;
593  else
594  {
595  assertain_character(',',text);
596  eat_whitespace(text);
597  }
598 
599  parse_integer(dummy, text);
600  res.push_back(dummy);
601  eat_whitespace(text);
602  }
603 
604  text.AdvanceChar();
605 }
606 
619 {
620  bool first = true; // To skip the first comma.
621 
622  // We need a temporary Array<Numeric>, so that we can use push_back
623  // to store the values. FIXME: Need also constructor for Vector from
624  // Array<Numeric>.
625  Array<Numeric> tres;
626 
627  // Make sure that the current character really is `[' and proceed.
628  assertain_character('[',text);
629  // There might have occured a linebreak, which is fine.
630 
631  eat_whitespace(text);
632 
633  // Read the elements of the vector (`]' means that we have
634  // reached the end):
635  while ( ']' != text.Current() )
636  {
637  Numeric dummy;
638 
639  if (first)
640  first = false;
641  else
642  {
643  assertain_character(',',text);
644  eat_whitespace(text);
645  }
646 
647  parse_numeric(dummy, text);
648  tres.push_back(dummy);
649  eat_whitespace(text);
650  }
651 
652  // Copy tres to res:
653  res.resize(tres.nelem());
654  res = tres;
655 
656  text.AdvanceChar();
657 }
658 
686 bool parse_method(Index& id,
687  Array<TokVal>& values,
688  ArrayOfIndex& output,
689  ArrayOfIndex& input,
690  SourceText& text,
691  const std::map<String, Index> MdMap,
692  const std::map<String, Index> WsvMap)
693 {
694  extern const Array<WsvRecord> wsv_data;
695  extern const Array<MdRecord> md_data;
696  extern const ArrayOfString wsv_group_names;
697 
698  Index wsvid; // Workspace variable id, is used to
699  // access data in wsv_data.
700 
701  // Clear all output variables:
702  id = 0;
703  values.resize( 0 );
704  output.resize( 0 );
705  input.resize( 0 );
706 
707  {
708  String methodname;
709  read_name(methodname, text);
710 
711  {
712  // Find method id:
713  const map<String, Index>::const_iterator i = MdMap.find(methodname);
714  if ( i == MdMap.end() )
715  throw UnknownMethod(methodname,
716  text.File(),
717  text.Line(),
718  text.Column());
719 
720  id = i->second;
721  }
722  // cout << "id=" << id << '\n';
723  // cout << "Method: " << md_data[id].Name() << '\n';
724  }
725 
726  eat_whitespace(text);
727 
728  // For generic methods the output and input workspace variables have
729  // to be parsed (given in round brackets).
730  if ( 0 < md_data[id].GOutput().nelem() + md_data[id].GInput().nelem() )
731  {
732  // cout << "Generic!" << id << md_data[id].Name() << '\n';
733  String wsvname;
734  bool first = true; // To skip the first comma.
735 
736  assertain_character('(',text);
737  eat_whitespace(text);
738 
739  // First read all output Wsvs:
740  for ( Index j=0 ; j<md_data[id].GOutput().nelem() ; ++j )
741  {
742  if (first)
743  first = false;
744  else
745  {
746  assertain_character(',',text);
747  eat_whitespace(text);
748  }
749 
750  read_name(wsvname, text);
751 
752  {
753  // Find Wsv id:
754  const map<String, Index>::const_iterator i = WsvMap.find(wsvname);
755  if ( i == WsvMap.end() )
756  throw UnknownWsv( wsvname,
757  text.File(),
758  text.Line(),
759  text.Column() );
760 
761  wsvid = i->second;
762  }
763 
764  // Check that this Wsv belongs to the correct group:
765  if ( wsv_data[wsvid].Group() != md_data[id].GOutput()[j] )
766  {
767  throw WrongWsvGroup( wsvname+" is not "+
768  wsv_group_names[md_data[id].GOutput()[j]]+", it is "+
769  wsv_group_names[wsv_data[wsvid].Group()],
770  text.File(),
771  text.Line(),
772  text.Column() );
773  }
774 
775  // Add this one to the list of output workspace variables:
776  output.push_back(wsvid);
777 
778  eat_whitespace(text);
779  }
780 
781  // Then read all input Wsvs:
782  for ( Index j=0 ; j<md_data[id].GInput().nelem() ; ++j )
783  {
784  if (first)
785  first = false;
786  else
787  {
788  assertain_character(',',text);
789  eat_whitespace(text);
790  }
791 
792  read_name(wsvname, text);
793 
794  {
795  // Find Wsv id:
796  const map<String, Index>::const_iterator i = WsvMap.find(wsvname);
797  if ( i == WsvMap.end() )
798  throw UnknownWsv( wsvname,
799  text.File(),
800  text.Line(),
801  text.Column() );
802 
803  wsvid = i->second;
804  }
805 
806  // Check that this Wsv belongs to the correct group:
807  if ( wsv_data[wsvid].Group() != md_data[id].GInput()[j] )
808  throw WrongWsvGroup( wsvname+" is not "+
809  wsv_group_names[md_data[id].GInput()[j]]+", it is "+
810  wsv_group_names[wsv_data[wsvid].Group()],
811  text.File(),
812  text.Line(),
813  text.Column() );
814 
815  // Add this one to the list of input workspace variables:
816  input.push_back(wsvid);
817 
818  eat_whitespace(text);
819  }
820 
821  assertain_character(')',text);
822  eat_whitespace(text);
823  }
824 
825  // Now look for the curly braces:
826  assertain_character('{',text);
827  eat_whitespace(text);
828 
829  // Now we have to deal with two different cases: Keywords with
830  // parameters, or (optionally) only a parameter without a keyword
831  // for methods that have only a single argument.
832  //
833  // We can distinguish the two cases if we check whether the current
834  // character is a letter. (If the parameter is specified directly it
835  // must be either a number, a +- sign or a quotation mark)
836  //
837  // KEYWORDS THAT START WITH A NUMBER WILL BREAK THIS CODE!!
838  //
839  for ( Index i=0 ; i<md_data[id].Keywords().nelem() ; ++i )
840  {
841  if (!isalpha(text.Current()) && 1==md_data[id].Keywords().nelem())
842  {
843  // Parameter specified directly, without a keyword. This is only
844  // allowed for single parameter methods!
845 
846  // We don't have to do anything here.
847  }
848  else
849  { // Look for the keywords and read the parameters:
850 
851  String keyname;
852  read_name(keyname,text);
853 
854  // Is the keyname the expected keyname?
855  if ( keyname != md_data[id].Keywords()[i] )
856  {
857  throw UnexpectedKeyword( keyname,
858  text.File(),
859  text.Line(),
860  text.Column());
861  }
862 
863  eat_whitespace(text);
864 
865  // Look for '='
866  assertain_character('=',text);
867  eat_whitespace(text);
868  }
869 
870  // Now parse the key value. This can be:
871  // String_t, Index_t, Numeric_t,
872  // Array_String_t, Array_Index_t, Vector_t,
873  switch (md_data[id].Types()[i])
874  {
875  case String_t:
876  {
877  String dummy;
878  parse_String(dummy, text);
879  values.push_back(dummy);
880  break;
881  }
882  case Index_t:
883  {
884  Index n;
885  parse_integer(n, text);
886  values.push_back(n);
887  break;
888  }
889  case Numeric_t:
890  {
891  Numeric n;
892  parse_numeric(n, text);
893  values.push_back(n);
894  break;
895  }
896  case Array_String_t:
897  {
898  ArrayOfString dummy;
899  parse_Stringvector(dummy, text);
900  values.push_back(dummy);
901  break;
902  }
903  case Array_Index_t:
904  {
905  ArrayOfIndex dummy;
906  parse_intvector(dummy, text);
907  values.push_back(dummy);
908  break;
909  }
910  case Vector_t:
911  {
912  Vector dummy;
913  parse_numvector(dummy, text);
914  values.push_back(dummy);
915  break;
916  }
917  default:
918  throw logic_error("Impossible parameter type.");
919  break;
920  }
921 
922  eat_whitespace(text);
923 
924  // Check:
925  // cout << "Value: " << md_data[id].Values()[i] << '\n';
926  }
927 
928 
929  // Now look for the closing curly braces.
930  // We have to catch Eot, because after a method description is a
931  // good place to end the control file.
932  try
933  {
934  assertain_character('}',text);
935  }
936  catch (const Eot x)
937  {
938  // cout << "EOT!!!!" << endl;
939  return true;
940  }
941  return false;
942 }
943 
957 void parse(Array<MRecord>& tasklist,
958  SourceText& text,
959  const std::map<String, Index> MdMap,
960  const std::map<String, Index> WsvMap)
961 {
962  extern const Array<MdRecord> md_data;
963  bool last = false;
964  // For method ids:
965  Index id;
966  // For keyword parameter values:
967  Array<TokVal> values;
968  // Output workspace variables (for generic methods):
969  ArrayOfIndex output;
970  // Input workspace variables (for generic methods):
971  ArrayOfIndex input;
972 
973  out3 << "\nParsing:\n";
974 
975  // cout << text ;
976 
977  eat_whitespace(text);
978 
979  while (!last)
980  {
981  last = parse_method(id,values,output,input,text,MdMap,WsvMap);
982 
983  // Append taks to task list:
984  tasklist.push_back(MRecord(id,values,output,input));
985 
986  {
987  // Everything in this block is just to generate some
988  // informative output.
989  extern const Array<WsvRecord> wsv_data;
990 
991  out3 << "- " << md_data[id].Name() << "\n";
992 
993  for ( Index j=0 ; j<values.nelem() ; ++j )
994  {
995  out3 << " "
996  << md_data[id].Keywords()[j] << ": "
997  << values[j] << '\n';
998  }
999 
1000  // Output workspace variables for generic methods:
1001  if ( 0 < md_data[id].GOutput().nelem() + md_data[id].GInput().nelem() )
1002  {
1003  out3 << " Output: ";
1004  for ( Index j=0 ; j<output.nelem() ; ++j )
1005  {
1006  out3 << wsv_data[output[j]].Name() << " ";
1007  }
1008  out3 << "\n";
1009 
1010  out3 << " Input: ";
1011  for ( Index j=0 ; j<input.nelem() ; ++j )
1012  {
1013  out3 << wsv_data[input[j]].Name() << " ";
1014  }
1015  out3 << "\n";
1016  }
1017  }
1018 
1019  // If last is set, then we have anyway reached the end of the
1020  // text, so we don't have to eat whitespace.
1021  if (!last)
1022  try
1023  {
1024  eat_whitespace(text);
1025  }
1026  catch (const Eot x)
1027  {
1028  last = true;
1029  }
1030  }
1031 }
1032 
1033 void parse_main(Array<MRecord>& tasklist, SourceText& text)
1034 {
1035  // extern const Array<MdRecord> md_data;
1036  // extern const Array<WsvRecord> wsv_data;
1037  extern const std::map<String, Index> MdMap;
1038  extern const std::map<String, Index> WsvMap;
1039 
1040  try
1041  {
1042  text.Init();
1043  parse(tasklist,text,MdMap,WsvMap);
1044  }
1045  catch (const Eot x)
1046  {
1047  // Unexpected end of the source text:
1048  out0 << "Unexpected end of control script.\n";
1049  out0 << "File: " << x.file() << '\n';
1050  out0 << "Line: " << x.line() << '\n';
1051  exit(true);
1052  }
1053  catch (const UnexpectedChar x)
1054  {
1055  // Unexpected Character:
1056  out0 << "Unexpected character:\n";
1057  out0 << x.what() << '\n';
1058  out0 << "File: " << x.file() << '\n';
1059  out0 << "Line: " << x.line() << '\n';
1060  out0 << "Column: " << x.column() << '\n';
1061  exit(true);
1062  }
1063  catch (const IllegalLinebreak x)
1064  {
1065  // A line break in an illegal position:
1066  out0 << "Illegal Line break:\n";
1067  out0 << x.what() << '\n';
1068  out0 << "File: " << x.file() << '\n';
1069  out0 << "Line: " << x.line() << '\n';
1070  exit(true);
1071  }
1072  catch (const UnknownMethod x)
1073  {
1074  // Method unknown:
1075  // [**This should give a hint on how to obtain a list of allowed
1076  // methods.]
1077  out0 << "Unknown Method:\n";
1078  out0 << x.what() << '\n';
1079  out0 << "File: " << x.file() << '\n';
1080  out0 << "Line: " << x.line() << '\n';
1081  out3 << "Column: " << x.column() << '\n';
1082  exit(true);
1083  }
1084  catch (const UnknownWsv x)
1085  {
1086  // Workspace variable unknown:
1087  // [**This should give a hint on how to obtain a list of allowed
1088  // Wsvs.]
1089  out0 << "Unknown workspace variable:\n";
1090  out0 << x.what() << '\n';
1091  out0 << "File: " << x.file() << '\n';
1092  out0 << "Line: " << x.line() << '\n';
1093  out3 << "Column: " << x.column() << '\n';
1094  exit(true);
1095  }
1096  catch (const WrongWsvGroup x)
1097  {
1098  // Workspace variable unknown:
1099  // [**This should give a hint on how to obtain a list of Wsvs in
1100  // this group.
1101  out0 << "Workspace variable belongs to the wrong group:\n";
1102  out0 << x.what() << '\n';
1103  out0 << "File: " << x.file() << '\n';
1104  out0 << "Line: " << x.line() << '\n';
1105  out3 << "Column: " << x.column() << '\n';
1106  exit(true);
1107  }
1108  catch (const UnexpectedKeyword x)
1109  {
1110  // Keyword unknown:
1111  // [**This should give a hint on how to obtain a list of allowed
1112  // keywords.]
1113  out0 << "Unknown keyword:\n";
1114  out0 << x.what() << '\n';
1115  out0 << "File: " << x.file() << '\n';
1116  out0 << "Line: " << x.line() << '\n';
1117  out3 << "Column: " << x.column() << '\n';
1118  exit(true);
1119  }
1120  catch (const ParseError x)
1121  {
1122  // General Parse Error (parent of all the above):
1123  out0 << "Parse error:\n";
1124  out0 << x.what() << '\n';
1125  out0 << "File: " << x.file() << '\n';
1126  out0 << "Line: " << x.line() << '\n';
1127  out0 << "Column: " << x.column() << '\n';
1128  exit(true);
1129  }
1130  catch (const runtime_error x)
1131  {
1132  cout << "Runtime error: ";
1133  cout << x.what() << '\n';
1134  }
1135  catch (const logic_error x)
1136  {
1137  cout << "Logic error: ";
1138  cout << x.what() << '\n';
1139  }
1140 
1141 }
UnknownMethod
Definition: exceptions.h:94
is_whitespace
bool is_whitespace(const char c)
Returns true if this character is considered whitespace.
Definition: parser.cc:168
SourceText::AppendFile
void AppendFile(const String &name)
Appends contents of file to the source text.
Definition: parser.cc:28
exceptions.h
The declarations of all the exception classes.
SourceText::mColumn
Index mColumn
Column position in the text.
Definition: parser.h:134
SourceText::Init
void Init()
This sets the pointer to the first existing character in the text.
Definition: parser.cc:117
SourceText::mSfName
ArrayOfString mSfName
Names associated with.
Definition: parser.h:140
parse_Stringvector
void parse_Stringvector(ArrayOfString &res, SourceText &text)
Read a vector of Strings.
Definition: parser.cc:530
SourceText::mText
ArrayOfString mText
The text.
Definition: parser.h:128
last
Numeric last(ConstVectorView x)
Gives the last value of a vector.
Definition: math_funcs.cc:83
first
Numeric first(ConstVectorView x)
Gives the first value of a vector.
Definition: math_funcs.cc:70
Array_Index_t
@ Array_Index_t
Definition: token.h:28
out0
Out0 out0
Level 0 output stream.
Definition: messages.cc:50
SourceText::LineBreak
bool & LineBreak()
Read the line break flag.
Definition: parser.h:116
MRecord
Method runtime data.
Definition: parser.h:32
Vector::resize
void resize(Index n)
Resize function.
Definition: matpackI.h:1467
IllegalLinebreak
Definition: exceptions.h:85
Vector_t
@ Vector_t
Definition: token.h:28
SourceText::mLine
Index mLine
Line position in the text.
Definition: parser.h:131
wsv_data
const Array< WsvRecord > wsv_data
Definition: workspace.cc:42
SourceText::mLineBreak
bool mLineBreak
Is set to true if the last operation caused a line break.
Definition: parser.h:144
eat_whitespace
void eat_whitespace(SourceText &text)
Eats whitespace.
Definition: parser.cc:193
ParseError
Definition: exceptions.h:40
WsvMap
std::map< String, Index > WsvMap
Definition: workspace_aux.cc:38
ParseError::file
virtual String file() const
Definition: exceptions.h:53
Index_t
@ Index_t
Definition: token.h:27
ParseError::column
virtual Index column() const
Definition: exceptions.h:55
Array< String >
SourceText::Line
Index Line()
Return the line number, but for the file that is associated with the current position.
Definition: parser.cc:102
parse_numeric
void parse_numeric(Numeric &n, SourceText &text)
Use a String stream to parse a floating point number.
Definition: parser.cc:508
String_t
@ String_t
Definition: token.h:27
SourceText::mSfLine
ArrayOfIndex mSfLine
Remember where which source file starts.
Definition: parser.h:137
MdMap
std::map< String, Index > MdMap
The map associated with md_data.
Definition: globals_2.cc:56
SourceText::AdvanceLine
void AdvanceLine()
Advances position pointer by one line.
Definition: parser.cc:65
messages.h
Declarations having to do with the four output streams.
ParseError::line
virtual Index line() const
Definition: exceptions.h:54
SourceText::Column
Index Column()
Return the current column.
Definition: parser.h:108
my_basic_string< char >
parse_String
void parse_String(String &res, SourceText &text)
Reads a String, complete with quotation marks.
Definition: parser.cc:285
read_name
void read_name(String &name, SourceText &text)
Reads name of method, keyword, or workspace variable.
Definition: parser.cc:232
Eot
Definition: exceptions.h:67
Numeric
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: arts.h:147
operator<<
ostream & operator<<(ostream &os, const SourceText &text)
Definition: parser.cc:151
wsv_group_names
ArrayOfString wsv_group_names
Definition: groups.cc:36
SourceText::File
const String & File()
Return the filename associated with the current position.
Definition: parser.cc:87
parse_method
bool parse_method(Index &id, Array< TokVal > &values, ArrayOfIndex &output, ArrayOfIndex &input, SourceText &text, const std::map< String, Index > MdMap, const std::map< String, Index > WsvMap)
Parse the Contents of text as ARTS control input.
Definition: parser.cc:686
SourceText
A smart class to hold the text for parsing.
Definition: parser.h:74
Numeric_t
@ Numeric_t
Definition: token.h:27
read_text_from_file
void read_text_from_file(ArrayOfString &text, const String &name)
Reads an ASCII file and appends the contents to the String vector text.
Definition: file.cc:206
parse_integer
void parse_integer(Index &n, SourceText &text)
Use a String stream to parse an integer number.
Definition: parser.cc:499
md_data
Array< MdRecord > md_data
The lookup information for the workspace methods.
Definition: globals_2.cc:53
out3
Out3 out3
Level 3 output stream.
Definition: messages.cc:56
parser.h
UnknownWsv
Definition: exceptions.h:103
Index
INDEX Index
The type to use for all integer numbers and indices.
Definition: arts.h:153
WrongWsvGroup
Definition: exceptions.h:112
UnexpectedChar
Definition: exceptions.h:76
SourceText::Current
char Current()
Return the current character.
Definition: parser.h:85
parse_main
void parse_main(Array< MRecord > &tasklist, SourceText &text)
The main function of the parser.
Definition: parser.cc:1033
read_integer
void read_integer(String &res, SourceText &text)
Reads an integer.
Definition: parser.cc:330
Array_String_t
@ Array_String_t
Definition: token.h:28
parse_intvector
void parse_intvector(ArrayOfIndex &res, SourceText &text)
Read a vector of integers.
Definition: parser.cc:574
file.h
This file contains basic functions to handle ASCII and binary (HDF) data files.
UnexpectedKeyword
Definition: exceptions.h:121
SourceText::AdvanceChar
void AdvanceChar()
Advance position pointer by one character.
Definition: parser.cc:36
parse
void parse(Array< MRecord > &tasklist, SourceText &text, const std::map< String, Index > MdMap, const std::map< String, Index > WsvMap)
Parse the Contents of text as ARTS control input.
Definition: parser.cc:957
Vector
The Vector class.
Definition: matpackI.h:389
parse_numvector
void parse_numvector(Vector &res, SourceText &text)
Read a vector of Numerics.
Definition: parser.cc:618
assertain_character
void assertain_character(char c, SourceText &text)
Make sure that the current character is equal to c and go to the next character.
Definition: parser.cc:262
Array::nelem
Index nelem() const
Number of elements.
Definition: array.h:115
methods.h
Declaration of the class MdRecord.
wsv_aux.h
Auxiliary header stuff related to workspace variable groups.
auto_wsv.h
Declares the enum type that acts as a handle for workspace variables. Also declares the workspace its...
read_numeric
void read_numeric(String &res, SourceText &text)
Reads a floating point number.
Definition: parser.cc:388
arts.h
The global header file for ARTS.