root/branches/maintenance/2.2.1/Modelica/Utilities/Strings.mo

Revision 463, 54.6 kB (checked in by hubertus, 22 months ago)

Created maintenance version from Dynasims version with minimal changes (no checksum, 1 graphics, a few improved documentation places, structurallyIncomplete annotations in Visualizers)

Line 
1package Strings "Operations on strings" 
2  function length "Returns length of string" 
3    extends Modelica.Icons.Function;
4    input String string;
5    output Integer result "Number of characters of string";
6  external "C" result=  ModelicaStrings_length(string);
7    annotation (preferedView="info", Documentation(info="<html>
8<h3><font color=\"#008000\">Syntax</font></h3>
9<blockquote><pre>
10Strings.<b>length</b>(string);
11</pre></blockquote>
12<h3><font color=\"#008000\">Description</font></h3>
13<p>
14Returns the number of characters of \"string\".
15</p>
16</html>"));
17  end length;
18 
19  function substring "Returns a substring defined by start and end index" 
20   
21    extends Modelica.Icons.Function;
22    input String string "String from which a substring is inquired";
23    input Integer startIndex(min=1) 
24      "Character position of substring begin (index=1 is first character in string)";
25    input Integer endIndex(min=1) "Character position of substring end";
26    output String result
27      "String containing substring string[startIndex:endIndex]";
28  external "C" result = 
29                      ModelicaStrings_substring(string,startIndex,endIndex);
30    annotation (  preferedView="info",
31  Documentation(info="<html>
32<h3><font color=\"#008000\">Syntax</font></h3>
33<blockquote><pre>
34string2 = Strings.<b>substring</b>(string, startIndex, endIndex);
35</pre></blockquote>
36<h3><font color=\"#008000\">Description</font></h3>
37<p>
38This function returns
39the substring from position startIndex
40up to and including position endIndex of \"string\" .
41</p>
42<p>
43If index, startIndex, or endIndex are not correct, e.g.,
44if endIndex &gt; length(string), an assert is triggered.
45</p>
46<h3><font color=\"#008000\">Example</font></h3>
47<blockquote><pre>
48  string1 := \"This is line 111\";
49  string2 := Strings.substring(string1,9,12); // string2 = \"line\"
50</pre></blockquote>
51</html>"));
52  end substring;
53 
54  function repeat "Repeat a string n times" 
55    extends Modelica.Icons.Function;
56    input Integer n(min=0) = 1 "Number of occurences";
57    input String string=" " "String that is repeated";
58    output String repeatedString "String containing n concatenated strings";
59    annotation (  preferedView="info",
60  Documentation(info="<html>
61<h3><font color=\"#008000\">Syntax</font></h3>
62<blockquote><pre>
63string2 = Strings.<b>repeat</b>(n);
64string2 = Strings.<b>repeat</b>(n, string=\" \");
65</pre></blockquote>
66<h3><font color=\"#008000\">Description</font></h3>
67<p>
68The first form returns a string consisting of n blanks.
69</p>
70<p>
71The second form returns a string consisting of n substrings
72defined by the optional argument \"string\".
73</p>
74</html>"));
75  algorithm 
76    repeatedString :="";
77    for i in 1:n loop
78       repeatedString := repeatedString + string;
79    end for;
80  end repeat;
81 
82  function compare "Compare two strings lexicographically" 
83    extends Modelica.Icons.Function;
84    input String string1;
85    input String string2;
86    input Boolean caseSensitive=true "= false, if case of letters is ignored";
87    output Modelica.Utilities.Types.Compare.Type result "Result of comparison";
88  external "C" result=  ModelicaStrings_compare(string1, string2, caseSensitive);
89    annotation (preferedView="info", Documentation(info="<html>
90<h3><font color=\"#008000\">Syntax</font></h3>
91<blockquote><pre>
92result = Strings.<b>compare</b>(string1, string2);
93result = Strings.<b>compare</b>(string1, string2, caseSensitive=true);
94</pre></blockquote>
95<h3><font color=\"#008000\">Description</font></h3>
96<p>
97Compares two strings. If the optional argument caseSensitive=false,
98upper case letters are treated as if they would be lower case letters.
99The result of the comparison is returned as:
100</p>
101<pre>
102  result = Modelica.Utilities.Types.Compare.Less     // string1 &lt; string2
103         = Modelica.Utilities.Types.Compare.Equal    // string1 = string2
104         = Modelica.Utilities.Types.Compare.Greater  // string1 &gt; string2
105</pre>
106<p>
107Comparison is with regards to lexicographical order,
108e.g., \"a\" &lt; \"b\";
109</p>
110</html>"));
111  end compare;
112 
113  function isEqual "Determine whether two strings are identical" 
114    extends Modelica.Icons.Function;
115    input String string1;
116    input String string2;
117    input Boolean caseSensitive=true 
118      "= false, if lower and upper case are ignored for the comparison";
119    output Boolean identical "True, if string1 is identical to string2";
120    annotation (  preferedView="info",
121  Documentation(info="<html>
122<h3><font color=\"#008000\">Syntax</font></h3>
123<blockquote><pre>
124Strings.<b>isEqual</b>(string1, string2);
125Strings.<b>isEqual</b>(string1, string2, caseSensitive=true);
126</pre></blockquote>
127<h3><font color=\"#008000\">Description</font></h3>
128<p>
129Compare whether two strings are identical,
130optionally ignoring case.
131</p>
132</html>"));
133  algorithm 
134    identical :=compare(string1, string2, caseSensitive) == Types.Compare.Equal;
135  end isEqual;
136  extends Modelica.Icons.Library;
137 
138  annotation (
139  version="1.0",
140  versionDate="2004-10-01",
141  preferedView="info",
142    Documentation(info="<HTML>
143<h3><font color=\"#008000\">Library content</font></h3>
144<p>
145Package <b>Strings</b> contains functions to manipulate strings.
146</p>
147<p>
148In the table below an example
149call to every function is given using the <b>default</b> options.
150</p>
151<table border=1 cellspacing=0 cellpadding=2>
152  <tr><th><b><i>Function</i></b></th><th><b><i>Description</i></b></th></tr>
153  <tr><td>len = <a href=\"Modelica:Modelica.Utilities.Strings.length\">length</a>(string)</td>
154      <td>Returns length of string</td></tr>
155  <tr><td>string2 = <a href=\"Modelica:Modelica.Utilities.Strings.substring\">substring</a>(string1,startIndex,endIndex)
156       </td>
157      <td>Returns a substring defined by start and end index</td></tr>
158  <tr><td>result = <a href=\"Modelica:Modelica.Utilities.Strings.repeat\">repeat</a>(n)<br>
159 result = <a href=\"Modelica:Modelica.Utilities.Strings.repeat\">repeat</a>(n,string)</td>
160      <td>Repeat a blank or a string n times.</td></tr>
161  <tr><td>result = <a href=\"Modelica:Modelica.Utilities.Strings.compare\">compare</a>(string1, string2)</td>
162      <td>Compares two substrings with regards to alphabetical order</td></tr>
163  <tr><td>identical =
164<a href=\"Modelica:Modelica.Utilities.Strings.isEqual\">isEqual</a>(string1,string2)</td>
165      <td>Determine whether two strings are identical</td></tr>
166  <tr><td>result = <a href=\"Modelica:Modelica.Utilities.Strings.count\">count</a>(string,searchString)</td>
167      <td>Count the number of occurrences of a string</td></tr>
168  <tr>
169<td>index = <a href=\"Modelica:Modelica.Utilities.Strings.find\">find</a>(string,searchString)</td>
170      <td>Find first occurrence of a string in another string</td></tr>
171<tr>
172<td>index = <a href=\"Modelica:Modelica.Utilities.Strings.findLast\">findLast</a>(string,searchString)</td>
173      <td>Find last occurrence of a string in another string</td></tr>
174  <tr><td>string2 = <a href=\"Modelica:Modelica.Utilities.Strings.replace\">replace</a>(string,searchString,replaceString)</td>
175      <td>Replace one or all occurrences of a string</td></tr>
176  <tr><td>stringVector2 = <a href=\"Modelica:Modelica.Utilities.Strings.sort\">sort</a>(stringVector1)</td>
177      <td>Sort vector of strings in alphabetic order</td></tr>
178  <tr><td>(token, index) = <a href=\"Modelica:Modelica.Utilities.Strings.scanToken\">scanToken</a>(string,startIndex)</td>
179      <td>Scan for a token (Real/Integer/Boolean/String/Identifier/Delimiter/NoToken)</td></tr>
180  <tr><td>(number, index) = <a href=\"Modelica:Modelica.Utilities.Strings.scanReal\">scanReal</a>(string,startIndex)</td>
181      <td>Scan for a Real constant</td></tr>
182  <tr><td>(number, index) = <a href=\"Modelica:Modelica.Utilities.Strings.scanInteger\">scanInteger</a>(string,startIndex)</td>
183      <td>Scan for an Integer constant</td></tr>
184  <tr><td>(boolean, index) = <a href=\"Modelica:Modelica.Utilities.Strings.scanBoolean\">scanBoolean</a>(string,startIndex)</td>
185      <td>Scan for a Boolean constant</td></tr>
186  <tr><td>(string2, index) = <a href=\"Modelica:Modelica.Utilities.Strings.scanString\">scanString</a>(string,startIndex)</td>
187      <td>Scan for a String constant</td></tr>
188  <tr><td>(identifier, index) = <a href=\"Modelica:Modelica.Utilities.Strings.scanIdentifier\">scanIdentifier</a>(string,startIndex)</td>
189      <td>Scan for an identifier</td></tr>
190  <tr><td>(delimiter, index) = <a href=\"Modelica:Modelica.Utilities.Strings.scanDelimiter\">scanDelimiter</a>(string,startIndex)</td>
191      <td>Scan for delimiters</td></tr>
192  <tr><td><a href=\"Modelica:Modelica.Utilities.Strings.scanNoToken\">scanNoToken</a>(string,startIndex)</td>
193      <td>Check that remaining part of string consists solely of <br>
194          white space or line comments (\"// ...\\n\").</td></tr>
195  <tr><td><a href=\"Modelica:Modelica.Utilities.Strings.syntaxError\">syntaxError</a>(string,index,message)</td>
196      <td> Print a \"syntax error message\" as well as a string and the <br>
197           index at which scanning detected an error</td></tr>
198</table>
199<p>
200The functions \"compare\", \"isEqual\", \"count\", \"find\", \"findLast\", \"replace\", \"sort\"
201have the optional
202input argument <b>caseSensitive</b> with default <b>true</b>.
203If <b>false</b>, the operation is carried out without taking
204into account whether a character is upper or lower case.
205</p>
206</HTML>"));
207 
208  function count "Count the number of non-overlapping occurrences of a string" 
209    extends Modelica.Icons.Function;
210    input String string "String that is analyzed";
211    input String searchString "String that is searched for in string";
212    input Integer startIndex(min=1)=1 "Start search at index startIndex";
213    input Boolean caseSensitive=true 
214      "= false, if lower and upper case are ignored for count";
215    output Integer result "Number of occurrences of 'searchString' in 'string'";
216    annotation (  preferedView="info",
217  Documentation(info="<html>
218<h3><font color=\"#008000\">Syntax</font></h3>
219<blockquote><pre>
220Strings.<b>count</b>(string, searchString)
221Strings.<b>count</b>(string, searchString, startIndex=1,
222                     caseSensitive=true)
223</pre></blockquote>
224<h3><font color=\"#008000\">Description</font></h3>
225<p>
226Returns the number of non-overlapping occurrences of string \"searchString\"
227in \"string\". The search is started at index \"startIndex\" (default = 1).
228If the optional argument \"caseSensitive\" is false,
229for the counting it does not matter whether a letter is upper
230or lower case.
231/p>
232</html>"));
233  protected 
234    Integer lenSearchString = length(searchString);
235    Integer i = startIndex;
236  algorithm 
237    result := 0;
238    while i <> 0 loop
239       i := find(string, searchString, i, caseSensitive);
240       if i > 0 then
241          result := result + 1;
242          i := i + lenSearchString;
243       end if;
244    end while;
245  end count;
246 
247  function find "Find first occurrence of a string within another string" 
248    extends Modelica.Icons.Function;
249    input String string "String that is analyzed";
250    input String searchString "String that is searched for in string";
251    input Integer startIndex(min=1)=1 "Start search at index startIndex";
252    input Boolean caseSensitive=true 
253      "= false, if lower and upper case are ignored for the search";
254     output Integer index
255      "Index of the beginning of the first occurrence of 'searchString' within 'string', or zero if not present";
256    annotation (  preferedView="info",
257  Documentation(info="<html>
258<h3><font color=\"#008000\">Syntax</font></h3>
259<blockquote><pre>
260index = Strings.<b>find</b>(string, searchString);
261index = Strings.<b>find</b>(string, searchString, startIndex=1,
262                     caseSensitive=true);
263</pre></blockquote>
264<h3><font color=\"#008000\">Description</font></h3>
265<p>
266Finds first occurence of \"searchString\" within \"string\"
267and return the corresponding index.
268Start search at index \"startIndex\" (default = 1).
269If the optional argument \"caseSensitive\" is false, lower
270and upper case are ignored for the search.
271If \"searchString\" is not found, a value of \"0\" is returned.
272</p>
273</html>
274"));
275  protected 
276    Integer lengthSearchString = length(searchString);
277    Integer len = lengthSearchString-1;
278    Integer i = startIndex;
279    Integer i_max = length(string) - lengthSearchString + 1;
280  algorithm 
281    index := 0;
282    while i <= i_max loop
283       if isEqual(substring(string,i,i+len),
284                  searchString, caseSensitive) then
285          index := i;
286          i := i_max + 1;
287       else
288          i := i+1;
289       end if;
290    end while;
291  end find;
292 
293  function findLast "Find last occurrence of a string within another string" 
294    extends Modelica.Icons.Function;
295    input String string "String that is analyzed";
296    input String searchString "String that is searched for in string";
297    input Integer startIndex(min=0)=0 
298      "Start search at index startIndex. If startIndex = 0, start at length(string)";
299    input Boolean caseSensitive=true 
300      "= false, if lower and upper case are ignored for the search";
301    output Integer index
302      "Index of the beginning of the last occurrence of 'searchString' within 'string', or zero if not present";
303    annotation (  preferedView="info",
304  Documentation(info="<html>
305<h3><font color=\"#008000\">Syntax</font></h3>
306<blockquote><pre>
307index = Strings.<b>findLast</b>(string, searchString);
308index = Strings.<b>findLast</b>(string, searchString,
309                         startIndex=length(string), caseSensitive=true,
310</pre></blockquote>
311<h3><font color=\"#008000\">Description</font></h3>
312<p>
313Finds first occurence of \"searchString\" within \"string\"
314when searching from the last character of \"string\"
315backwards, and return the corresponding index.
316Start search at index \"startIndex\" (default = length(string)).
317If the optional argument \"caseSensitive\" is false, lower
318and upper case are ignored for the search.
319If \"searchString\" is not found, a value of \"0\" is returned.
320</p>
321</html>
322"));
323  protected 
324    Integer lenString = length(string);
325    Integer lenSearchString = length(searchString);
326    Integer i;
327  algorithm 
328    i := if startIndex == 0 then lenString-lenSearchString+1 else startIndex;
329    index := 0;
330    while i >= 1 loop
331       if isEqual(substring(string,i,i+lenSearchString-1),
332                  searchString, caseSensitive) then
333          index := i;
334          i := 0;
335       else
336          i := i-1;
337       end if;
338    end while;
339  end findLast;
340 
341  function replace
342    "Replace non-overlapping occurrences of a string from left to right" 
343    extends Modelica.Icons.Function;
344    input String string "String to be modified";
345    input String searchString
346      "Replace non-overlapping occurrences of 'searchString' in 'string' with 'replaceString'";
347    input String replaceString
348      "String that replaces 'searchString' in 'string'";
349    input Integer startIndex=1 "Start search at index startIndex";
350    input Boolean replaceAll=true 
351      "if false, replace only the first occurrence, otherwise all occurrences";
352    input Boolean caseSensitive=true 
353      "= false, if lower and upper case are ignored when searching for searchString";
354    output String result "Resultant string of replacement operation";
355    annotation (  preferedView="info",
356  Documentation(info="<html>
357<h3><font color=\"#008000\">Syntax</font></h3>
358<blockquote><pre>
359Strings.<b>replace</b>(string, searchString, replaceString);
360Strings.<b>replace</b>(string, searchString, replaceString,
361                startIndex=1, replaceAll=true, caseSensitive=true);
362</pre></blockquote>
363<h3><font color=\"#008000\">Description</font></h3>
364<p>
365Search in \"string\" for \"searchString\" and replace the found
366substring by \"replaceString\".
367<p>
368<ul>
369<li> The search starts at the first character of \"string\",
370     or at character position \"startIndex\",
371     if this optional argument is provided.</li>
372<li> If the optional argument \"replaceAll\" is <b>true</b> (default),
373     all occurrences of \"searchString\" are replaced.
374     If the argument is <b>false</b>, only the first occurrence
375     is replaced. </li>
376<li> The search for \"searchString\" distinguishes upper and lower
377     case letters. If the optional argument \"caseSensitive\" is
378     <b>false</b>,
379     the search ignores whether letters are upper
380     or lower case. </li>
381</ul>
382<p>
383The function returns the \"string\" with the
384performed replacements.
385</p>
386</html>"));
387  protected 
388    Integer lenString = length(string);
389    Integer lenSearchString = length(searchString);
390    Integer i = startIndex;
391    Integer i_found;
392  algorithm 
393    result := if startIndex == 1 then "" else substring(string,1,startIndex-1);
394    while i > 0 loop
395       i_found := find(string, searchString, i, caseSensitive);
396       if i_found > 0 then
397          result := if i_found == 1 then 
398                       replaceString else 
399                       result + (if i_found-1<i then "" else substring(string, i, i_found-1)) + replaceString;
400          i := i_found + lenSearchString;
401          if i > lenString then
402             i := 0;
403          elseif not replaceAll then
404             result := result + substring(string, i, lenString);
405             i := 0;
406          end if;
407       elseif lenString<i then
408          i := 0;
409       else
410          result := result + substring(string, i, lenString);
411          i := 0;
412       end if;
413    end while;
414  end replace;
415 
416  function sort "Sort vector of strings in alphabetic order" 
417    extends Modelica.Icons.Function;
418    input String stringVector1[:] "vector of strings";
419    input Boolean caseSensitive=true 
420      "= false, if lower and upper case are ignored when comparing elements of stringVector1";
421    output String stringVector2[size(stringVector1,1)] 
422      "string1 sorted in alphabetical order";
423    /* shellsort algorithm; should be improved later */
424  protected 
425    Integer gap;
426    Integer i;
427    Integer j;
428    String tempString;
429    Integer nStringVector1 = size(stringVector1,1);
430    Boolean swap;
431  algorithm 
432    stringVector2 := stringVector1;
433    gap := div(nStringVector1,2);
434   
435    while gap > 0 loop
436       i := gap;
437       while i < nStringVector1 loop
438          j := i-gap;
439          if j >= 0 then
440             swap := compare(stringVector2[j+1], stringVector2[j+gap+1], caseSensitive)
441                     == Modelica.Utilities.Types.Compare.Greater;
442          else
443             swap := false;
444          end if;
445       
446          while swap loop
447             tempString := stringVector2[j+1];
448             stringVector2[j+1] := stringVector2[j+gap+1];
449             stringVector2[j+gap+1] := tempString;
450             j := j - gap;
451             if j >= 0 then
452                swap := compare(stringVector2[j+1], stringVector2[j+gap+1], caseSensitive)
453                        == Modelica.Utilities.Types.Compare.Greater;
454             else
455                swap := false;
456             end if;
457          end while;
458          i := i + 1;
459       end while;
460       gap := div(gap,2);
461    end while;
462   
463    annotation (preferedView="info",Documentation(info="<HTML>
464<h3><font color=\"#008000\">Syntax</font></h3>
465<blockquote><pre>
466stringVector2 = Streams.<b>sort</b>(stringVector1);
467stringVector2 = Streams.<b>sort</b>(stringVector1, caseSensitive=true);
468</pre></blockquote>
469<h3><font color=\"#008000\">Description</font></h3>
470<p>
471Function <b>sort</b>(..) sorts a string vector stringVector1
472in lexicographical order and returns the result in stringVector2.
473If the optional argument \"caseSensitive\" is <b>false</b>, lower
474and upper case letters are not distinguished.
475</p>
476<h3><font color=\"#008000\">Example</font></h3>
477<blockquote><pre>
478  s1 = {\"force\", \"angle\", \"pressure\"};
479  s2 = Strings.sort(s1);
480       -> s2 = {\"angle\", \"force\", \"pressure\"};
481</pre></blockquote>
482</HTML>"));
483  end sort;
484 
485  function scanToken "Scan for the next token and return it" 
486    extends Modelica.Icons.Function;
487    input String string "String to be scanned";
488    input Integer startIndex(min=1) = 1 
489      "Start scanning of string at character startIndex";
490    input Boolean unsigned=false 
491      "= true, if Real and Integer tokens shall not start with a sign";
492    output Types.TokenValue token "Scanned token";
493    output Integer nextIndex
494      "Index of character after the found token; = 0, if NoToken";
495    annotation (preferedView="info", Documentation(info="<html>
496<h3><font color=\"#008000\">Syntax</font></h3>
497<blockquote><pre>
498(token, nextIndex) = Strings.<b>scanToken</b>(string, startIndex, unsigned=false);
499</pre></blockquote>
500<h3><font color=\"#008000\">Description</font></h3>
501<p>
502Function <b>scanToken</b> scans the string starting at index
503\"startIndex\" and returns the next token, as well as the
504index directly after the token. The returned token is a record
505that holds the type of the token and the value of the token:
506</p>
507<table border=1 cellspacing=0 cellpadding=2>
508  <tr><td>token.tokenType</td>
509      <td>Type of the token, see below</td></tr>
510  <tr><td>token.real</td>
511      <td>Real value if tokenType == TokenType.RealToken</td></tr>
512  <tr><td>token.integer</td>
513      <td>Integer value if tokenType == TokenType.IntegerToken</td></tr>
514  <tr><td>token.boolean</td>
515      <td>Boolean value if tokenType == TokenType.BooleanToken</td></tr>
516  <tr><td>token.string</td>
517      <td>String value if tokenType == TokenType.StringToken/IdentifierToken/DelimiterToken</td></tr>
518</table>
519<p>
520Variable token.tokenType is an enumeration (emulated as a package
521with constants) that can have the following values:
522</p>
523<pre>
524   import T = Modelica.Utilities.Types.TokenType;
525</pre>
526<table border=1 cellspacing=0 cellpadding=2>
527  <tr><td>T.RealToken</td>
528      <td>Modelica Real literal (e.g., 1.23e-4)</td></tr>
529  <tr><td>T.IntegerToken</td>
530      <td>Modelica Integer literal (e.g., 123)</td></tr>
531  <tr><td>T.BooleanToken</td>
532      <td>Modelica Boolean literal (e.g., false)</td></tr>
533  <tr><td>T.StringToken</td>
534      <td>Modelica String literal (e.g., \"string 123\")</td></tr>
535  <tr><td>T.IdentifierToken</td>
536      <td>Modelica identifier (e.g., \"force_a\")</td></tr>
537  <tr><td>T.DelimiterToken</td>
538      <td>any character without white space that does not appear<br>
539          as first character in the tokens above (e.g., \"&\")</td></tr>
540  <tr><td>T.NoToken</td>
541      <td>White space, line comments and no other token<br>
542          until the end of the string</td></tr>
543</table>
544<p>
545Modelica line comments (\"// ... end-of-line/end-of-string\")
546as well as white space is ignored.
547If \"unsigned=true\", a Real or Integer literal
548is not allowed to start with a \"+\" or \"-\" sign.
549</p>
550<h3><font color=\"#008000\">Example</font></h3>
551<blockquote><pre>
552  import Modelica.Utilities.Strings.*;
553  import T = Modelica.Utilities.Types.TokenType;
554  (token, index) := scanToken(string);
555  <b>if</b> token.tokenType == T.RealToken <b>then</b>
556     realValue := token.real;
557  <b>elseif</b> token.tokenType == T.IntegerToken <b>then</b>
558     integerValue := token.integer;
559  <b>elseif</b> token.tokenType == T.BooleanToken<b> then</b>
560     booleanValue := token.boolean;
561  <b>elseif</b> token.tokenType == T.Identifier <b>then</b>
562     name := token.string;
563  <b>else</b>
564     syntaxError(string,index,\"Expected Real, Integer, Boolean or identifier token\");
565  <b>end if</b>;
566</pre></blockquote>
567</html>"));
568  protected 
569    Integer startTokenIndex;
570  algorithm 
571    // Initialize token
572    token.real :=0.0;
573    token.integer :=0;
574    token.boolean :=false;
575    token.string :="";
576   
577    // skip white space and line comments
578    startTokenIndex := Advanced.skipLineComments(string, startIndex);
579    if startTokenIndex > length(string) then
580      token.tokenType := Types.TokenType.NoToken;
581      nextIndex := startTokenIndex;
582    else
583      // scan Integer number
584        (nextIndex, token.integer) := Advanced.scanInteger(string, startTokenIndex, unsigned);
585         token.tokenType := Types.TokenType.IntegerToken;
586     
587      // scan Real number
588      if nextIndex == startTokenIndex then
589        (nextIndex, token.real) :=Advanced.scanReal(string, startTokenIndex, unsigned);
590         token.tokenType := Types.TokenType.RealToken;
591      end if;
592     
593      // scan String
594      if nextIndex == startTokenIndex then
595         (nextIndex,token.string) := Advanced.scanString(string, startTokenIndex);
596          token.tokenType:= Types.TokenType.StringToken;
597      end if;
598     
599      // scan Identifier or Boolean
600      if nextIndex == startTokenIndex then
601         (nextIndex,token.string) := Advanced.scanIdentifier(string, startTokenIndex);
602         if nextIndex > startTokenIndex then
603            if token.string == "false" then
604               token.string := "";
605               token.boolean :=false;
606               token.tokenType := Types.TokenType.BooleanToken;
607            elseif token.string == "true" then
608               token.string := "";
609               token.boolean := true;
610               token.tokenType := Types.TokenType.BooleanToken;
611            else
612               token.tokenType := Types.TokenType.IdentifierToken;
613            end if;
614         end if;
615      end if;
616     
617      // scan Delimiter
618      if nextIndex == startTokenIndex then
619         token.string :=substring(string, startTokenIndex, startTokenIndex);
620         token.tokenType := Types.TokenType.DelimiterToken;
621         nextIndex := startTokenIndex + 1;
622      end if;
623    end if;
624  end scanToken;
625 
626  function scanReal
627    "Scan for the next Real number and trigger an assert if not present" 
628    extends Modelica.Icons.Function;
629    input String string "String to be scanned";
630    input Integer startIndex(min=1)=1 
631      "Start scanning of string at character startIndex";
632    input Boolean unsigned=false 
633      "= true, if Real token shall not start with a sign";
634    input String message="" 
635      "Message used in error message if scan is not successful";
636    output Real number "Value of real number";
637    output Integer nextIndex "index of character after the found number";
638    annotation (preferedView="info",Documentation(info="<html>
639<h3><font color=\"#008000\">Syntax</font></h3>
640<blockquote><pre>
641             number = Strings.<b>scanReal</b>(string);
642(number, nextIndex) = Strings.<b>scanReal</b>(string, startIndex=1,
643                                            unsigned=false, message=\"\");
644</pre></blockquote>
645<h3><font color=\"#008000\">Description</font></h3>
646<p>
647The first form, \"scanReal(string)\", scans \"string\" for a
648Real number with leading white space and returns the value.
649</p>
650<p>
651The second form, \"scanReal(string,startIndex,unsigned)\",
652scans the string starting at index
653\"startIndex\", checks whether the next token is a Real literal
654and returns its value as a Real number, as well as the
655index directly after the Real number.
656If the optional argument \"unsigned\" is <b>true</b>,
657the real number shall not have a leading \"+\" or \"-\" sign.
658</p>
659<p>
660If the required Real number with leading white space
661is not present in \"string\",  an assert is triggered.
662</p>
663</html>"));
664  algorithm 
665    (nextIndex, number) :=Advanced.scanReal(string, startIndex, unsigned);
666    if nextIndex == startIndex then
667       nextIndex :=Advanced.skipWhiteSpace(string, startIndex);
668       if unsigned then
669          syntaxError(string, nextIndex, "Expected a Real number without a sign " + message);
670       else
671          syntaxError(string, nextIndex, "Expected a Real number " + message);
672       end if;
673    end if;
674  end scanReal;
675 
676  function scanInteger
677    "Scan for the next Integer number and trigger an assert if not present" 
678    extends Modelica.Icons.Function;
679    input String string "String to be scanned";
680    input Integer startIndex(min=1)=1 
681      "Start scanning of string at character startIndex";
682    input Boolean unsigned=false 
683      "= true, if Integer token shall not start with a sign";
684    input String message="" 
685      "Message used in error message if scan is not successful";
686    output Integer number "Value of Integer number";
687    output Integer nextIndex "Index of character after the found number";
688    annotation (preferedView="info",Documentation(info="<html>
689<h3><font color=\"#008000\">Syntax</font></h3>
690<blockquote><pre>
691             number = Strings.<b>scanInteger</b>(string);
692(number, nextIndex) = Strings.<b>scanInteger</b>(string, startIndex=1,
693                                               unsigned=false, message=\"\");
694</pre></blockquote>
695<h3><font color=\"#008000\">Description</font></h3>
696<p>
697Function <b>scanInteger</b> scans the string starting at index
698\"startIndex\", checks whether the next token is an Integer literal
699and returns its value as an Integer number, as well as the
700index directly after the Integer number. An assert is triggered,
701if the scanned string does not contain an Integer literal with optional
702leading white space.
703</p>
704</html>"));
705  algorithm 
706    (nextIndex, number) :=Advanced.scanInteger(string, startIndex, unsigned);
707    if nextIndex == startIndex then
708       nextIndex :=Advanced.skipWhiteSpace(string, startIndex);
709       if unsigned then
710          syntaxError(string, nextIndex, "Expected an Integer number without a sign " + message);
711       else
712          syntaxError(string, nextIndex, "Expected an Integer number " + message);
713       end if;
714    end if;
715  end scanInteger;
716 
717  function scanBoolean
718    "Scan for the next Boolean number and trigger an assert if not present" 
719    extends Modelica.Icons.Function;
720    input String string "String to be scanned";
721    input Integer startIndex(min=1)=1 
722      "Start scanning of string at character startIndex";
723    input String message="" 
724      "Message used in error message if scan is not successful";
725    output Boolean number "Value of Boolean";
726    output Integer nextIndex "Index of character after the found number";
727    annotation (preferedView="info",Documentation(info="<html>
728<h3><font color=\"#008000\">Syntax</font></h3>
729<blockquote><pre>
730             number = Strings.<b>scanB