1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935
|
<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
<head>
<title>CODA Expressions</title>
<link rel="stylesheet" href="../css/codadoc.css" type="text/css" />
</head>
<body>
<div class="main">
<h1>CODA Expressions</h1>
<p>CODA comes with an advanced expression language that is able to perform calculations on product data. The expression language is primarilay used in the definitions of the product formats to formally describe how variable sizes, offsets, etc. are calculated. However, the expression language is also used within e.g. the codafind and codaeval tools to formulate queries on data products. The expression language provides a means to specify locations in a file, read values from a file and apply calculations on these values.</p>
<p>The expression language is a basic language in ASCII format. In this document we will describe the language and provide a <a href="#bnf">formal definition</a> using the ISO/IEC 14977 EBNF (Extended Backus-Naur Form) format.</p>
<p>The expression language knows 5 different types: <i>integer</i>, <i>float</i>, <i>string</i>, <i>boolean</i>, and <i>node</i>. <i>integer</i> and <i>float</i> represent integer and floating point values, <i>string</i> represents text data, <i>boolean</i> represents logical values (true/false), and <i>node</i> represents locations in a data file.</p>
<p>When we talk about the 'type of an expression' we refer to the type of the value that will result from evaluating the expression. A float expression will thus result in a floating point value and a boolean expression in a true/false value.</p>
<p>Expressions can range from being very simple (specifying just a constant value) to very complex (using various functions/operations to calculate the resulting value). An expression of one type can make use of sub-expressions of another type. For instance, a boolean expresssion can return the result of a comparison of two string expressions.</p>
<p>In addition to expressions for each of the five data types there is also a sixth category of expressions, those that do not return any value. These expressions are referred to as <i>void</i> expressions (i.e. statements).</p>
<p>The CODA expressions can thus be categorized in the following six groups:</p>
<ul>
<li><a href="#void">void expressions</a>: statements</li>
<li><a href="#boolean">boolean expressions</a>: expressions that return either True or False</li>
<li><a href="#integer">integer expressions</a>: expressions that return a numerical value</li>
<li><a href="#float">float expressions</a>: expressions that return a floating point value</li>
<li><a href="#string">string expressions</a>: expressions that return a character string</li>
<li><a href="#node">node expressions</a>: expressions that refer to data in the product file</li>
</ul>
<p>It should be noted that the expression language allows arbitrary whitespace (in the form of space characters) between the components of an expression.</p>
<h2 id="void">void expressions</h2>
<p>void expressions are statements. They won't return a value and can only be used at the topmost level of an expression.</p>
<h3>operators</h3>
<p>There are two void operators. One is the sequence operator '<code>;</code>'. This operator is used to instruct the sequential execution of two or more statements. The other operator is the assignment operator '<code>=</code>', which is used to assign values to product variables.</p>
<p>Example:</p>
<div class="fragment"><code><i>$count</i>[0] = 100; <i>$count</i>[1] = 200; <i>$count</i>[2] = 300</code></div>
<p>This will set the first three elements of the 1-dimensional product variable 'count' to 100, 200, and 300 respectively.</p>
<p>Product variables can be either scalars or 1-dimensional arrays. The array subscript '<code>[]</code>' is only used for product variables that are arrays. For scalar product variables one should use e.g. '<code><i>$count</i> = 100</code>'.</p>
<h3>functions</h3>
<h5>for indexvar = integer to integer (step integer) do void</h5>
<p>The <code>for</code> expression executes the void expression after '<code>do</code>' in a loop. The loop will terminate as soon as the index '<code>indexvar</code>' exceeds the value of the integer expression after '<code>to</code>'. The index '<code>indexvar</code>' can be any of three variables that can be used for keeping indices: <code><i>i</i></code>, <code><i>j</i></code>, or <code><i>k</i></code>. The step value is optional. The step may be negative, in which case the loop index will decrease with each step. The current value of the loop index can be used inside the void expression using the index integer expression '<code><i>i</i></code>', '<code><i>j</i></code>', or '<code><i>k</i></code>'.</p>
<p>Example:</p>
<div class="fragment"><code><b>for</b> <i>i</i> = 0 <b>to</b> 2 <b>do</b> <i>$count</i>[<i>i</i>] = 100 * <i>i</i></code></div>
<p>This expression has the same effect as the example provided in the previous section.</p>
<h2 id="boolean">boolean expressions</h2>
<p>A boolean expression is an expression that results in a true or false value.</p>
<h3>constant values</h3>
<p>There are two possible constant values '<code>true</code>' and '<code>false</code>'.</p>
<h3>operators</h3>
<p>There are three logical operators that operate on boolean values: AND, OR, and NOT ('<code>&&</code>', '<code>||</code>', and '<code>!</code>'). Boolean expressions can be put between braces ( '<code>(</code>' and '<code>)</code>' ) in order to guide the evaluation order.</p>
<p>The AND and OR expressions are lazy evaluated. This means that the second argument to AND will not be evaluated if the first argument already evaluated to false, and for OR similarly if the first argument already evaluated to true.</p>
<p>Integer, float, and string expressions can be compared using the following relations: equality ('<code>==</code>'), inequality ('<code>!=</code>'), less than ('<code><</code>'), less than or equal ('<code><=</code>'), greater than ('<code>></code>'), or greater than or equal ('<code>>=</code>'). The relative ordering of strings (to determine whether one string is larger than the other) will be based on the (unsigned) integer value of each byte character.</p>
<p>Integers cannot be compared directly to floats. To compare a float value with an integer value, first convert the integer value to a float using the 'float()' function.</p>
<h3>functions</h3>
<h5>isnan(float)</h5>
<p>Returns true if (and only if) the floating point value is NaN (the special 'Not a Number' value).</p>
<h5>isinf(float)</h5>
<p>Returns true if (and only if) the floating point value is +Inf or -Inf (minus or plus infinity).</p>
<h5>ismininf(float)</h5>
<p>Returns true if (and only if) the floating point value is -Inf (minus infinity).</p>
<h5>isplusinf(float)</h5>
<p>Returns true if (and only if) the floating point value is +Inf (plus infinity).</p>
<h5>regex(string, string)</h5>
<p>Matches a string against a regular expression pattern. The first parameter is the pattern and the second parameter is the string that it should match against.</p>
<p>The function will return true if the pattern matches (and false otherwise).</p>
<p>Note that if you want to use '\' characters in your pattern you should either provide the pattern as a 'raw string' (using the 'r' prefix) or use double escaping. For example, if you want to match for a "word" character (\w) you should either use 'r"\w"' or '"\\w"'</p>
<p>The regular expression engine that is used is <a href="http://www.pcre.org/">PCRE</a>. Please refer to the manual of this software package for an overview of the syntax and options for constructing a pattern. Note that the version of PCRE that ships with CODA has been build using default options. The pattern is <i>compiled</i> with the <code>PCRE_DOTALL</code> and <code>PCRE_DOLLAR_ENDONLY</code> options.</p>
<h5>exists(node)</h5>
<p>With the '<code>exists</code>' function it is possible to check whether a path exists inside a product. This can be used to check the availability of optional available record fields or to just check whether a certain path exists at all. The function will only return true if it is possible to traverse the path and false otherwise.</p>
<p>Example:</p>
<div class="fragment"><code><b>if</b>(<b>exists</b>(/calibration), <b>int</b>(/calibration/num_values), 0)</code></div>
<p>This will return the value of the num_values parameter if the calibration data set exists and 0 otherwise.</p>
<h5>exists(node, boolean)</h5>
<p>This function only works if node points to an array in the product. It will then walk the elements of the array (in ascending order) until it finds an element for which the boolean expression returns true, or, if none of the array elements match, will return false.</p>
<p>Example:</p>
<div class="fragment"><code><b>exists</b>(/calibration/value, <b>float</b>(.) > 10.0)</code></div>
<p>This will return true if any of the elements '/calibration/value[]' has a value > 10, and false otherwise.</p>
<h5>all(node, boolean)</h5>
<p>This function works just as the previous function, but will return false as soon as it finds an element for which the boolean expression returns false, or, if all elements match, will return true.</p>
<p>Example:</p>
<div class="fragment"><code><b>all</b>(/calibration/value, <b>float</b>(.) > 10.0)</code></div>
<p>This will return true if all of the elements '/calibration/value[]' have a value > 10, and false otherwise.</p>
<h5>if(boolean, boolean, boolean)</h5>
<p>If the first boolean expression argument evaluates to true the second argument is evaluated and its result returned, otherwise the third argument is evaluated and its result returned.</p>
<h5>at(node, boolean)</h5>
<p>Evaluate the boolean expression as provided in the second argument with the current node position moved according to the expression from the first argument. This function is recommended if evaluating the boolean expression requires multiple navigations to the same common node position.</p>
<h5>with(indexvar = integer, boolean)</h5>
<p>Evaluate the boolean expression as provided in the second argument while using the given <code>indexvar</code> (which can be either <code><i>i</i></code>, <code><i>j</i></code>, or <code><i>k</i></code>) as precalculated/cached value. This is useful if e.g. an expression needs to use an integer value from a product several times and you only want to read the value once.</p>
<p>Example:</p>
<div class="fragment"><code><b>with</b>(<i>k</i> = <b>int</b>(/data/intvalue), <i>k</i> > 10 || <i>k</i> < 0)</code></div>
<p>This will be faster than using '<code><b>int</b>(/data/intvalue) > 10 || <b>int</b>(/data/intvalue) < 0</code>'.</p>
<h2 id="integer">integer expressions</h2>
<p>An integer expression is an expression that results in an integer value.</p>
<p>All integer expressions are evaluated using a signed 64 bit integer.</p>
<h3>constant values</h3>
<p>Constants can be any integer number. However, it should be possible to represent the number by a 64 bit signed integer.</p>
<h3>variables</h3>
<p>There are two kinds of variables that can be used as integer expression: product variables and index variables. CODA only supports integer variables (i.e. variables can not contain boolean, floating point, or string data).</p>
<p>Product variables can be seen as a caching mechanism for expression results. A product variable is a named scalar or a one-dimensional array that is attached to an open product. Note that product variables can only be referred to if they have been defined in the CODA product format definition for the open product file. The initialisation expression for a product variable is fixed and defined as part of the product format definition. Product variables are initialized the first time a value is requested from it (it will thus not impact the performance of opening a product file).<br />
Product variables are referenced using a '<code>$</code>' character followed by the name of the product variable. If the product variable is an array then an additional (zero-based) array subscript should also be provided using '<code>[]</code>'. For example '<code>$foo</code>' will return the value of the scalar product variable 'foo' and '<code>$bar[10]</code>' will return the 11-th array element from the 1-dimensional product variable 'bar'.</p>
<p>Inside a for loop or '<code>with</code>' function the current value of the loop/with index can be retrieved by using the corresponding '<code><i>i</i></code>', '<code><i>j</i></code>', or '<code><i>k</i></code>' expression. These are called index variables.</p>
<h3>operators</h3>
<p>The following operations are provided: addition ('<code>+</code>'), subtraction ('<code>-</code>'), multiplication ('<code>*</code>'), division ('<code>/</code>'), modulo ('<code>%</code>'), bitwise and ('<code>&</code>'), and bitwise or ('<code>|</code>').</p>
<p>A unary '<code>-</code>' before an integer expression can be used to turn the sign of an integer.</p>
<p>Integer expressions can be put between braces ( '<code>(</code>' and '<code>)</code>' ) in order to guide the evaluation order.</p>
<h3>functions</h3>
<h5>int(bool)</h5>
<p>Convert the boolean value to an integer value.</p>
<p>This is equivalent to calling '<code><b>if</b>(bool, 1, 0)</code>'</p>
<h5>int(node)</h5>
<p>Reads the value at the node as an integer. If the node does not point to data that represents an integer value this will result in an error.</p>
<p>When the integer is stored as an unsigned 64 bit integer the value is returned as a signed 64 bit integer by converting all values >= 2^63 into negative values (e.g. 2^64 - 1 becomes -1). Integer values >= 2^64 are not supported.</p>
<h5>int(string)</h5>
<p>Convert the string to an integer value.</p>
<p>The rules for conversion are the same as for specifying a constant integer value in the expression language.</p>
<h5>abs(integer)</h5>
<p>Returns the absolute value of an integer as an integer.</p>
<h5>max(integer, integer)</h5>
<p>Returns the maximum of both integers.</p>
<h5>max(node, integer)</h5>
<p>This function only works if node points to an array in the product. It will then walk the elements of the array, evaluate the integer expression for each element and return the maximum of those results.</p>
<h5>min(integer, integer)</h5>
<p>Returns the minimum of both integers.</p>
<h5>min(node, integer)</h5>
<p>This function only works if node points to an array in the product. It will then walk the elements of the array, evaluate the integer expression for each element and return the minimum of those results.</p>
<h5>dim(node, integer)</h5>
<p>Will return the size of a specific dimension of the array at the given node.</p>
<p>Example:</p>
<div class="fragment"><code><b>numelements</b>(/calibration/value)==<b>dim</b>(/calibration/value, 0) * <b>dim</b>(/calibration/value, 1)</code></div>
<p>This comparison should return true if '<code>/calibration/value</code>' is a two dimensional array.</p>
<p>Note that the only CODA expression functions that deal with unflattened array dimensions are '<code>dim</code>' and '<code>num_dims</code>', all other operations treat arrays as flat arrays.</p>
<h5>numdims(node)</h5>
<p>Will return the number of dimensions of the array at the given node.</p>
<p>Note that the only CODA expression functions that deal with unflattened array dimensions are '<code>dim</code>' and '<code>num_dims</code>', all other operations treat arrays as flat arrays.</p>
<h5>numelements(node)</h5>
<p>Will return the number of fields if the node points to a record or the number of array elements if the node points to an array. If the node points to a scalar the function will return 1.</p>
<p>Example:</p>
<div class="fragment"><code><b>numelements</b>(/calibration/value)==<b>int</b>(/calibration/num_values)</code></div>
<p>This comparison should return true of the product is consistent.</p>
<h5>count(node, boolean)</h5>
<p>This function is similar to the <code><b>exists</b>(<i>node</i>, <i>boolean</i>)</code> function, but will return the total number of array elements for which the boolean expression evaluates to true.</p>
<p>Example:</p>
<div class="fragment"><code>100.0 * <b>float</b>(<b>count</b>(/calibration/value, <b>float</b>(.) > 10.0))) / <b>float</b>(<b>numelements</b>(/calibration/value))</code></div>
<p>This calculates the percentage of values for which the value is larger than 10.</p>
<h5>add(node, integer)</h5>
<p>This function only works if node points to an array in the product. It will then walk the elements of the array, evaluate the integer expression for each element and return the sum of those results.</p>
<p>Example:</p>
<div class="fragment"><code><b>float</b>(<b>add</b>(/calibration/value, <b>int</b>(.))) / <b>float</b>(<b>numelements</b>(/calibration/value))</code></div>
<p>This will calculate the average of the integer values in the value array.</p>
<h5>length(string)</h5>
<p>This function will return the length (number of characters) of the string argument.</p>
<p>Example:</p>
<div class="fragment"><code><b>length</b>("A String")==8</code></div>
<p>This should always be true.</p>
<h5>length(node)</h5>
<p>This function only works if node points to string data. It will return the length (number of characters) of the string pointed to by the node.</p>
<p>Example:</p>
<div class="fragment"><code><b>length</b>(/some/data)==<b>length</b>(<b>str</b>(/some/data))</code></div>
<p>This should always be true.</p>
<h5>bitsize(node)</h5>
<p>This function will return the bit size of the data item pointed to by '<code>node</code>'. If the bit size is not available (e.g. for HDF products) this function will return -1.</p>
<h5>bytesize(node)</h5>
<p>This function will return the byte size (rounded up) of the data item pointed to by '<code>node</code>'. If the byte size is not available (e.g. for HDF products) this function will return -1.</p>
<h5>productversion()</h5>
<p>This function will return the version number of the product format for the file. The version number is a CODA specific version number (the number can be found in the CODA product format definition documentation for the data file).</p>
<h5>filesize()</h5>
<p>This function will return the size of the file as a number of bytes.</p>
<h5>bitoffset(node)</h5>
<p>This function will return the bit offset of the data item pointed to by '<code>node</code>' relative to the start of the file. If the bit offset is not available (e.g. for HDF products) this function will return -1.</p>
<h5>byteoffset(node)</h5>
<p>This function will return the byte offset (rounded down) of the data item pointed to by '<code>node</code>' relative to the start of the file. If the byte offset is not available (e.g. for HDF products) this function will return -1.</p>
<h5>index(node)</h5>
<p>This function will return the 0-based index (field number or array element index) that was used to get from the parent node to the current node.</p>
<p>Example:</p>
<div class="fragment"><code><b>index</b>(/calibration/value[6])==6</code></div>
<p>This should always be true.</p>
<h5>index(node, boolean)</h5>
<p>This function is similar to the <code><b>exists</b>(<i>node</i>, <i>boolean</i>)</code> function, but will return the 0-based array index of the first array element for which the boolean expression evaluates to true. If none of the array elements match, the function will return -1.</p>
<h5>if(boolean, integer, integer)</h5>
<p>If the boolean expression evaluates to true the second argument is evaluated and its result returned, otherwise the third argument is evaluated and its result returned.</p>
<p>Example:</p>
<div class="fragment"><code><b>if</b>(<b>float</b>(/calibration/value[0]) < 0.0, -1, 1)</code></div>
<p>This will return the sign of the first array element.</p>
<h5>unboundindex(node, boolean)</h5>
<p>This function has the same behavior as the <code><b>index</b>(<i>node</i>, <i>boolean</i>)</code> function, but it will not check for the array size. This function only has use for binary/ascii data where data outside the boundary can be reinterpreted as array elements this way. Since arrays are treated as unlimited arrays, you should be careful that the expression will not try to read beyond the boundary of the overall ascii/binary block of data (e.g. the size of the file). You can do this by providing an explicit termination condition (see <code><b>unboundindex(node, boolean, boolean)</b></code>) or by including a check of e.g. the <code>byteoffset</code> against the <code>filesize</code> in the boolean expression of the second argument.</p>
<p>You should integrate the termination condition in the boolean expression of the second argument (and <i>not</i> provide an explicit termination condition as third argument) if you want the function to return the number of the last array element when the termination condition is reached.</p>
<h5>unboundindex(node, boolean, boolean)</h5>
<p>This function is similar to <code><b>unboundindex(node, boolean)</b></code>, but has an additional argument at the end to explicitly provide a termination condition.</p>
<p>You should provide an explicit termination condition if you want the function to return -1 if no elements were found matching the boolean expression of the second argument.</p>
<p>The function will, for each array element, always first evaluate the termination condition. Only if that evaluates to false will the boolean expression of the second argument be evaluated (otherwise the function will return -1).</p>
<h5>at(node, integer)</h5>
<p>Evaluate the integer expression as provided in the second argument with the current node position moved according to the expression from the first argument. This function is recommended if evaluating the integer expression requires multiple navigations to the same common node position.</p>
<h5>with(indexvar = integer, integer)</h5>
<p>Evaluate the integer expression as provided in the second argument while using the given <code>indexvar</code> (which can be either <code><i>i</i></code>, <code><i>j</i></code>, or <code><i>k</i></code>) as precalculated/cached value. This is useful if e.g. an expression needs to use an integer value from a product several times and you only want to read the value once.</p>
<p>Example:</p>
<div class="fragment"><code><b>with</b>(<i>k</i> = <b>int</b>(/data/intvalue), <b>if</b>(<i>k</i> > 10, <i>k</i> + 10, <i>k</i> - 5))</code></div>
<p>This will be faster than using '<code><b>if</b>(<b>int</b>(/data/intvalue) > 10, <b>int</b>(/data/intvalue) + 10, <b>int</b>(/data/intvalue) - 5)</code>', since the value <code>/data/intvalue</code> will only be read once instead of 3 times.</p>
<h2 id="float">float expressions</h2>
<p>A float expression is an expression that results in a floating point value.</p>
<p>All float expressions are evaluated using a IEE754 double precision floating point value.</p>
<p>Any expression that expects a float expression as input will also except an integer expression. In these cases the resulting integer value will be silently cast to a floating point value (e.g. as if the <code>float(integer)</code> function was used).</p>
<h3>constant values</h3>
<p>Floating point constant values should have a '<code>.</code>' and/or an exponent. The exponent should start with either a '<code>D</code>' (fortran style) or '<code>E</code>' character (case insensitive). The special values '<code>nan</code>', and '<code>inf</code>' can be used to represent the IEEE754 special cases not-a-number and infinity.</p>
<p>Examples:</p>
<div class="fragment"><code><pre>
1.0
.1
-1.
1.0E-20
-.09e99
.133000D+03
1e-6
nan
inf
-inf
+inf
</pre></code></div>
<h3>operators</h3>
<p>The following operations are provided: addition ('<code>+</code>'), subtraction ('<code>-</code>'), multiplication ('<code>*</code>'), division ('<code>/</code>'), modulo ('<code>%</code>'), and power ('<code>^</code>').</p>
<p>A unary '<code>-</code>' before a float expression can be used to turn the sign of the value.</p>
<p>Float expressions can be put between braces ( '<code>(</code>' and '<code>)</code>' ) in order to guide the evaluation order.</p>
<h3>functions</h3>
<h5>float(node)</h5>
<p>Reads the value at the node as a floating point value. If the node does not point to data that represents an floating point or integer value this will result in an error.</p>
<h5>float(integer)</h5>
<p>Convert the integer to a floating point value.</p>
<p>For large integer values this can result in a loss of precision.</p>
<h5>float(string)</h5>
<p>Convert the string to a floating point value.</p>
<p>The rules for conversion are the same as for specifying a constant floating point value in the expression language.</p>
<h5>abs(float)</h5>
<p>Returns the absolute value of a floating point value as a floating point value.</p>
<h5>ceil(float)</h5>
<p>Returns the smallest integral value not less than the argument as a floating point value.</p>
<h5>floor(float)</h5>
<p>Returns the largest integral value not greater than the argument as a floating point value.</p>
<h5>round(float)</h5>
<p>Returns the floating point value, rounded to nearest integer (halfway away from zero).</p>
<h5>max(float, float)</h5>
<p>Returns the maximum of both floating point values.</p>
<h5>max(node, float)</h5>
<p>This function only works if node points to an array in the product. It will then walk the elements of the array, evaluate the floating point expression for each element and return the maximum of those results.</p>
<h5>min(float, float)</h5>
<p>Returns the minimum of both floating point values.</p>
<h5>min(node, float)</h5>
<p>This function only works if node points to an array in the product. It will then walk the elements of the array, evaluate the floating point expression for each element and return the minimum of those results.</p>
<h5>time(string, string)</h5>
<p>Returns a double value giving the amount of seconds since 2000-01-01T00:00:00.000000 for the date/time string value that is provided as the first argument and using the date/time format pattern that is provided by the second argument.</p>
<p>An overview of the time format patterns is provided in the section <a href="#timeformat">date/time format patterns</a>.</p>
<h5>add(node, float)</h5>
<p>This function only works if node points to an array in the product. It will then walk the elements of the array, evaluate the float expression for each element and return the sum of those results.</p>
<p>Example:</p>
<div class="fragment"><code><b>float</b>(<b>add</b>(/calibration/value, <b>float</b>(.))) / <b>float</b>(<b>numelements</b>(/calibration/value))</code></div>
<p>This will calculate the average of the floating point values in the value array.</p>
<h5>if(boolean, float, float)</h5>
<p>If the boolean expression evaluates to true the second argument is evaluated and its result returned, otherwise the third argument is evaluated and its result returned.</p>
<h5>at(node, float)</h5>
<p>Evaluate the float expression as provided in the second argument with the current node position moved according to the expression from the first argument. This function is recommended if evaluating the float expression requires multiple navigations to the same common node position.</p>
<h5>with(indexvar = integer, float)</h5>
<p>Evaluate the float expression as provided in the second argument while using the given <code>indexvar</code> (which can be either <code><i>i</i></code>, <code><i>j</i></code>, or <code><i>k</i></code>) as precalculated/cached value. This is useful if e.g. an expression needs to use an integer value from a product several times and you only want to read the value once.</p>
<p>Example:</p>
<div class="fragment"><code><b>with</b>(<i>k</i> = <b>int</b>(/data/intvalue), <b>if</b>(<i>k</i> <= 0, 0.0, <b>if</b>(<i>k</i> >= 100, 1.0, <i>k</i> / 100.0)))</code></div>
<p>This will be faster than using '<code><b>if</b>(<b>int</b>(/data/intvalue) <= 0, 0.0, <b>if</b>(<b>int</b>(/data/intvalue) >= 100, 1.0, <b>int</b>(/data/intvalue) / 100.0))</code>'.</p>
<h2 id="string">string expressions</h2>
<p>A string expression is an expression that results in a character string.</p>
<p>A string value is simply a sequence of bytes. No special character encoding interpretation is used and all byte values (0-255) are allowed for a character (e.g. no special string termination character is applied).</p>
<h3>constant values</h3>
<p>A string constant is provided by a sequence of printable ASCII characters between double quote characters. The double quote character itself or any characters that are not ASCII printable characters can be included in string constants by using an escape sequence. An escape sequence is a '\' followed by either a character or by a 3 digit octal number of the byte value (for instance, '\060' is equal to 'A'). The following table lists the possible escape sequences that are allowed:</p>
<table class="fancy" width="60%">
<tr><th>Escape sequence</th><th>ASCII Character</th><th>Decimal code</th></tr>
<tr><td align="center">\a</td><td>Bell</td><td align="right">7</td></tr>
<tr><td align="center">\b</td><td>Backspace</td><td align="right">8</td></tr>
<tr><td align="center">\t</td><td>Tab</td><td align="right">9</td></tr>
<tr><td align="center">\n</td><td>Linefeed</td><td align="right">10</td></tr>
<tr><td align="center">\v</td><td>Vertical tab</td><td align="right">11</td></tr>
<tr><td align="center">\f</td><td>Formfeed</td><td align="right">12</td></tr>
<tr><td align="center">\r</td><td>Carriage return</td><td align="right">13</td></tr>
<tr><td align="center">\"</td><td>"</td><td align="right">34</td></tr>
<tr><td align="center">\'</td><td>'</td><td align="right">39</td></tr>
<tr><td align="center">\\</td><td>\</td><td align="right">92</td></tr>
<tr><td align="center">\nnn</td><td>A byte value equal to the octal number 'nnn'</td><td align="right"> </td></tr>
</table>
<p>Examples:</p>
<div class="fragment"><code><pre>
"Hello World!"
""
"Line 1\nLine 2\n"
"A string with a \000 character"
"How to quote a '\"'?"
</pre></code></div>
<p>By default all escaped characters are interpreted and turned into their single character equivalents. However, if you precede a string constant by the letter 'r' this translation will not be performed and you will get the raw string value. For instance, '"abc \\ \" "' will be translated to 'abc \ " ', whereas 'r"abc \\ \" "' will remain as 'abc \\ \" '.</p>
<h3>operators</h3>
<p>Strings can be concatenated using the '<code>+</code>' operator.</p>
<h3>functions</h3>
<h5>str(integer)</h5>
<p>Convert the integer value into a string value (using decimal notation).</p>
<h5>str(node)</h5>
<p>Reads the string value for the data element pointed to by the node parameter.</p>
<h5>str(node, integer)</h5>
<p>Similar to the previous function, but now limit the read to a maximum number of bytes as indicated by the second argument. Note that the length of the returned string may be less than the provided maximum if the length of the data in the product is less than the indicated maximum.</p>
<h5>bytes(node)</h5>
<p>Reads the data element pointed to by the node parameter as a raw byte array. This function differs from <code><b>str</b>(node)</code> because it is not restricted to reading text data, but can be used independent of the type of data at the node position, as long as the data is stored in an 'ascii' or 'binary' formatted product (e.g. it can be used to read a binary record).</p>
<h5>bytes(node, integer)</h5>
<p>Similar to the previous function, but now explicitly set the number of bytes that should be read (as indicated by the second argument). The function will always read the given number of bytes, even if this exceeds the length of the data item at the node position. If the number of bytes from the node position till the end of the file is less than the provided maximum, CODA will return an error.</p>
<h5>bytes(node, integer, integer)</h5>
<p>Similar to the previous function, but now explicitly set both the byte offset relative to the node (as second argument) and the number of bytes that should be read (as third argument). Both the offset and number of bytes may exceed the range of the data at the given node. This means that the offset can be negative and/or the offset+length may exceed that of the data item at the node position. If the range exceeds the boundaries of the file (e.g. global offset is negative or offset+length exceeds the file length), CODA will return an error.</p>
<h5>substr(integer, integer, string)</h5>
<p>Return a substring of the third argument, where the first argument indicates the 0-based offset and the second argument the length. The values for both the offset and length arguments should be greater or equal to 0 and the sum of the offset and length parameters should not exceed the string length of the third argument.</p>
<p>Example:</p>
<div class="fragment"><code>"bcd" == <b>substr</b>(1, 3, "abcdef")</code></div>
<p>This should always be true.</p>
<h5>ltrim(string)</h5>
<p>Return the string with all white space characters removed from the left (=start of string).</p>
<p>The following characters are considered white space: space, tab, newline, carriage return.</p>
<h5>rtrim(string)</h5>
<p>Return the string with all white space characters removed from the right (=end of string).</p>
<p>The following characters are considered white space: space, tab, newline, carriage return.</p>
<h5>trim(string)</h5>
<p>Return the string with all white space characters removed from the left and right (=beginning and end of string).</p>
<p>The following characters are considered white space: space, tab, newline, carriage return.</p>
<h5>add(node, string)</h5>
<p>This function only works if node points to an array in the product. It will then walk the elements of the array (in ascending order), evaluate the string expression for each element and return the concatenated string of the results.</p>
<h5>max(string, string)</h5>
<p>Returns the maximum of both string values.</p>
<h5>max(node, string)</h5>
<p>This function only works if node points to an array in the product. It will then walk the elements of the array, evaluate the string expression for each element and return the maximum of those results.</p>
<h5>min(string, string)</h5>
<p>Returns the minimum of both string values.</p>
<h5>min(node, string)</h5>
<p>This function only works if node points to an array in the product. It will then walk the elements of the array, evaluate the string expression for each element and return the minimum of those results.</p>
<h5>regex(string, string, integer)</h5>
<p>Matches a string against a regular expression pattern. The first parameter is the pattern, the second parameter is the string that it should match against and the third parameter is the index of the substring whos value should be returned.</p>
<p>Note that an index value of 0 will give the full match of the pattern, and indices 1..n are the indices for the substrings.</p>
<p>If no match for the specified substring was found an empty string will be returned.</p>
<p>The regular expression engine that is used is <a href="http://www.pcre.org/">PCRE</a>. Please refer to the manual of this software package for an overview of the syntax and options for constructing a pattern and for an explanation of the concept of 'substrings'. Note that the version of PCRE that ships with CODA has been build using default options. The pattern is <i>compiled</i> with the <code>PCRE_DOTALL</code> and <code>PCRE_DOLLAR_ENDONLY</code> options.</p>
<p>For example, <code>regex(r"a+(\d+)", "aaa1234aaa", 0)</code> will return <code>"aaa1234"</code> and <code>regex(r"a+(\d+)", "aaa1234aaa", 1)</code> will return <code>"1234"</code>.</p>
<h5>regex(string, string, string)</h5>
<p>Matches a string against a regular expression pattern. The first parameter is the pattern, the second parameter is the string that it should match against and the third parameter is the name of the substring whos value should be returned.</p>
<p>If no match for the specified substring was found an empty string will be returned.</p>
<p>The regular expression engine that is used is <a href="http://www.pcre.org/">PCRE</a>. Please refer to the manual of this software package for an overview of the syntax and options for constructing a pattern and for an explanation of the concept of 'substrings'. Note that the version of PCRE that ships with CODA has been build using default options. The pattern is <i>compiled</i> with the <code>PCRE_DOTALL</code> and <code>PCRE_DOLLAR_ENDONLY</code> options.</p>
<p>For example, <code>regex(r"a+(?'foo'\d+)", "aaa1234aaa", "foo")</code> will return <code>"1234"</code>.</p>
<h5>productformat()</h5>
<p>Returns the name of the underlying format (e.g. 'binary', 'xml', 'hdf5') of the file. A file that can be opened by CODA will always have an associated product format.</p>
<h5>productclass()</h5>
<p>Returns the name of the productclass of the file. If the file does not have a productclass an empty string will be returned.</p>
<h5>producttype()</h5>
<p>Returns the name of the productype of the file. If the file does not have a producttype an empty string will be returned.</p>
<h5>filename()</h5>
<p>Returns the filename (<i>not</i> including directory path components, but including the file extension) as a string.</p>
<h5>strtime(float)</h5>
<p>Returns a string representation of the time value, interpreted as seconds since 2000-01-01T00:00:00.000000, using the date/time format "yyyy-MM-dd'T'HH:mm:ss.SSSSSS".</p>
<h5>strtime(float, string)</h5>
<p>Returns a string representation of the time value, interpreted as seconds since 2000-01-01T00:00:00.000000, using the date/time format as provided by the second argument.</p>
<p>An overview of the time format patterns is provided in the section <a href="#timeformat">date/time format patterns</a>.</p>
<h5>if(boolean, string, string)</h5>
<p>If the boolean expression evaluates to true the second argument is evaluated and its result returned, otherwise the third argument is evaluated and its result returned.</p>
<h5>at(node, string)</h5>
<p>Evaluate the string expression as provided in the second argument with the current node position moved according to the expression from the first argument. This function is recommended if evaluating the string expression requires multiple navigations to the same common node position.</p>
<p>Example:</p>
<div class="fragment"><code><b>at</b>(/some/data, <b>with</b>(<i>k</i> = <b>length</b>(.), <b>substr</b>(<i>k</i> / 2, <i>k</i> - (<i>k</i> / 2), <b>str</b>(.))))</code></div>
<p>This will be faster than using '<code><b>with</b>(<i>k</i> = <b>length</b>(/some/data), <b>substr</b>(<i>k</i> / 2, <i>k</i> - (<i>k</i> / 2), <b>str</b>(/some/data)))</code>'.</p>
<h5>with(indexvar = integer, string)</h5>
<p>Evaluate the string expression as provided in the second argument while using the given <code>indexvar</code> (which can be either <code><i>i</i></code>, <code><i>j</i></code>, or <code><i>k</i></code>) as precalculated/cached value. This is useful if e.g. an expression needs to use an integer value from a product several times and you only want to read the value once.</p>
<p>Example:</p>
<div class="fragment"><code><b>with</b>(<i>k</i> = <b>length</b>(/some/data), <b>substr</b>(<i>k</i> / 2, <i>k</i> - (<i>k</i> / 2), <b>str</b>(/some/data)))</code></div>
<p>This will be faster than using '<code><b>substr</b>(<b>length</b>(/some/data) / 2, <b>length</b>(/some/data) - (<b>length</b>(/some/data) / 2), <b>str</b>(/some/data))</code>'.</p>
<h2 id="node">node expressions</h2>
<p>A node describes a path into a product file similar to XPath for XML.</p>
<p>How to construct a path (i.e. which identifiers to use) depends entirely on the format of the data product. The basis is that a product is composed of compound elements that can be traversed using identifiers (i.e. fields in a record) or using indices (i.e. elements of an array).</p>
<p>Within CODA the format of field names is restricted to identifiers, which means that the first character should be a-z or A-Z and all subsequent characters should be a-z, A-Z, 0-9, or _. Instead of specifying a field name, it is also possible to provide a zero-based index of the field between '{', '}'. So '<code>/first_field</code>' and '<code>/{0}</code>' are equivalent.</p>
<p>Array indices are 0-based indices on the flattened view of an array. This means that if an array is defined as having more than one dimension the index as used in a node expression should be between 0 and the total number of array elements (exclusive). For example, for a [10,8] array, the index should be >= 0 and <= 79. The CODA product format definition document will always show the dimension order in such a way that the last dimension is the fastest running dimension.</p>
<p>A node can be specified as a relative or absolute path. An absolute path starts at the root of the product and the expression starts with either '<code>/</code>', '<code>[</code>' (start of a top-level index reference), or '<code>@</code>' (start of a top-level attribute reference). Relative paths start with either '<code>.</code>', '<code>..</code>', or '<code>:</code>'. When a node starts with '<code>..</code>' this is just a shorthand for '<code>./..</code>', which refers to the parent node of the current node. The relative paths '<code>.</code>' and '<code>:</code>' both refer to the current node position but with a slightly different meaning. The '<code>:</code>' node will always refer to the node with which the evaluation was started, whereas the location of '<code>.</code>' will depend on where the expression is used (for instance, if '<code>.</code>' is used within the evaluation of the second argument of a '<code>count(node, boolean)</code>' expression it will refer to the array element in '<code>node</code>' that is being evaluated). The node position with which the evaluation is started is either equal to the node to which the expression is attached or, if the expression is not attached to a specific product parameter, it is the root of the product.</p>
<p>There is a special node expression '<code>asciiline</code>' that can only be used in expressions for product format definitions for ASCII products. The '<code>asciiline</code>' expression can only be used as start point of a node expression and will map the view of a file to an array of strings where each string corresponds with a single line (including end of line character(s)) of the ascii file. For example the expression <code><b>bitoffset</b>(<b>asciiline</b>[<b>index</b>(<b>asciiline</b>, <b>str</b>(., 1) != "#")])</code> will give the bitoffset in the file of the first line that does not start with a '#' character.</p>
<h2 id="timeformat">date/time format patterns</h2>
<p>For parsing and printing date/time values in textual format, CODA uses a pattern description that is largely based on the Unicode Technical Standard #35 regarding Date Format Patterns. Note that only a very specific subset of patterns are supported and that the pattern for the abbreviated month deviates from the standard.</p>
<p>In a date/time format pattern certain character series have special meaning and correspond to the various components of a date/time value. Characters that need to be matched literally can be included between two single quote characters ('). Any alphabetical character that is to be treated literally <i>has</i> to be included between quotes. This includes the special characters '|' and '*'. Other characters may be included between quotes (but don't have to). Two single quotes represents a literal single quote, either inside or outside single quotes.</p>
<p>To provide a list of multiple patterns that are tried in sequence until one succeeds, provide the list of patterns separated by '|' (vertical bar) characters in a single format string. When converting a time value to a string, the first pattern of a list will be used for the conversion.</p>
<p>A pattern for a date/time component can have a '*' appended to the format to indicate that it should use leading spaces instead of leading zeros (both for parsing and for printing).</p>
<p>The table below provides an overview of the patterns that are supported in CODA for date/time formats:</p>
<table class="fancy" width="60%">
<tr><th>Pattern</th><th>Description</th></tr>
<tr><td>yyyy</td><td>4-digit year value [0001..9999]</td></tr>
<tr><td>MM</td><td>2-digit month value [01..12]</td></tr>
<tr><td>MMM</td><td>3-character abbreviation of the month: "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC".<br />Lower-case versions of these strings are also accepted when parsing.</td></tr>
<tr><td>dd</td><td>2-digit day of month value [01..31]</td></tr>
<tr><td>DDD</td><td>3-digit day of year value [001..366]</td></tr>
<tr><td>HH</td><td>2-digit hour of day value [00..23]</td></tr>
<tr><td>mm</td><td>2-digit minute of hour value [00..59]</td></tr>
<tr><td>ss</td><td>2-digit second of minute value [00..60]<br />Note that a possible leap second value is supported in a string value, but it is not taken into account in a conversion (i.e. it is treated as '00' of the next minute) unless explicitly specified otherwise.</td></tr>
<tr><td>S<br />SS<br />SSS<br />...<td>n-digit fraction of a second.<br />A 3-digit fraction would represent milliseconds and a 6-digit fraction would represent microseconds.<br />Values will be printed truncated (i.e. 12.159 seconds with format ss.SS will be printed as 12.15). Any digits beyond the 6th digit will be ignored when parsing (i.e. values will always be truncated at microsecond resolution).</td></tr>
</table>
<p>Several examples of formats and their string values for the date 4 July 2012 19:32:56.123456:</p>
<ul>
<li>"yyyy-MM-dd" : "2012-07-04"</li>
<li>"yyyy MM* dd*" : "2012 7 4"</li>
<li>"yyyy-MM-dd'T'HH:mm:ss" : "2012-07-04T19:32:56"</li>
<li>"dd-MMM-yyyy HH:mm:ss.SSSSSS" : "04-JUL-2012 19:32:56.123456"</li>
<li>"yyyy DDD" : "2012 186"</li>
</ul>
<h2 id="bnf">formal definition</h2>
<p><pre>
alpha =
'a'|'b'|'c'|'d'|'e'|'f'|'g'|'h'|'i'|'j'|'k'|'l'|'m'|
'n'|'o'|'p'|'q'|'r'|'s'|'t'|'u'|'v'|'w'|'x'|'y'|'z'|
'A'|'B'|'C'|'D'|'E'|'F'|'G'|'H'|'I'|'J'|'K'|'L'|'M'|
'N'|'O'|'P'|'Q'|'R'|'S'|'T'|'U'|'V'|'W'|'X'|'Y'|'Z' ;
character = alpha | digit |
' '|'!'|'"'|'#'|'$'|'%'|'&'|"'"|'('|')'|'*'|'+'|','|
'-'|'.'|'/'|':'|';'|'<'|'='|'>'|'?'|'@'|'['|'\'|']'|
'^'|'_'|'`'|'{'|'|'|'}'|'~' ;
identifier = alpha, [{alpha | digit | '_'}] ;
indexvar = 'i'|'j'|'k'
digit = '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9' ;
sign = '+'|'-' ;
intvalue = {digit} ;
floatvalue = (intvalue, '.', [intvalue] | '.', intvalue), [('E' | 'e' | 'D' | 'd'), [sign], intvalue] ;
stringvalue = '"', [{character-('\', '"') | '\' character}], '"' ;
voidexpr =
'$' identifier '=' intexpr |
'$' identifier '[' intexpr ']' '=' intexpr |
voidexpr ';' voidexpr |
'for' indexvar '=' intexpr 'to' intexpr 'do' voidexpr |
'for' indexvar '=' intexpr 'to' intexpr 'step' intexpr 'do' voidexpr |
'for' indexvar '=' intexpr 'to' intexpr 'step' intexpr 'do' voidexpr |
'goto' '(' node ')' |
'with', '(', indexvar, '=', intexpr, ',', voidexpr, ')' ;
boolexpr =
'true' |
'false' |
boolexpr, '&&', boolexpr |
boolexpr, '||', boolexpr |
'!', boolexpr |
intexpr, '==', intexpr |
intexpr, '!=', intexpr |
intexpr, '>', intexpr |
intexpr, '>=', intexpr |
intexpr, '<', intexpr |
intexpr, '<=', intexpr |
floatexpr, '==', floatexpr |
floatexpr, '==', intexpr |
intexpr, '==', floatexpr |
floatexpr, '!=', floatexpr |
floatexpr, '!=', intexpr |
intexpr, '!=', floatexpr |
floatexpr, '>', floatexpr |
floatexpr, '>', intexpr |
intexpr, '>', floatexpr |
floatexpr, '>=', floatexpr |
floatexpr, '>=', intexpr |
intexpr, '>=', floatexpr |
floatexpr, '<', floatexpr |
floatexpr, '<', intexpr |
intexpr, '<', floatexpr |
floatexpr, '<=', floatexpr |
floatexpr, '<=', intexpr |
intexpr, '<=', floatexpr |
stringexpr, '==', stringexpr |
stringexpr, '!=', stringexpr |
stringexpr, '>', stringexpr |
stringexpr, '>=', stringexpr |
stringexpr, '<', stringexpr |
stringexpr, '<=', stringexpr |
'(', boolexpr, ')' |
'regex', '(', stringexpr, ',', stringexpr ')' |
'exists', '(', node, ')' |
'exists', '(', node, ',', boolexpr, ')' |
'all', '(', node, ',', boolexpr, ')' |
'if', '(' boolexpr, ',', boolexpr, ',', boolexpr, ')' |
'with', '(', indexvar, '=', intexpr, ',', boolexpr, ')' ;
intexpr =
intvalue |
'int', '(', intexpr, ')' |
'int', '(', boolexpr, ')' |
'int', '(', node, ')' |
'int', '(', stringexpr, ')' |
'$', identifier |
'$', identifier, '[', intexpr, ']' |
indexvar |
'-', intexpr |
'+', intexpr |
intexpr, '+', intexpr |
intexpr, '-', intexpr |
intexpr, '*', intexpr |
intexpr, '/', intexpr |
intexpr, '%', intexpr |
intexpr, '&', intexpr |
intexpr, '|', intexpr |
'(', intexpr, ')' |
'abs', '(', intexpr, ')' |
'max', '(', node, ',', intexpr, ')' |
'max', '(', intexpr, ',', intexpr, ')' |
'min', '(', node, ',', intexpr, ')' |
'min', '(', intexpr, ',', intexpr, ')' |
'dim', '(', node, ',', intexpr ')' |
'numdims', '(', node, ')' |
'numelements', '(', node, ')' |
'count', '(' node, ',', boolexpr, ')' |
'add', '(' node, ',', intexpr, ')' |
'length', '(', stringexpr, ')' |
'length', '(', node, ')' |
'bitsize', '(', node, ')' |
'bytesize', '(', node, ')' |
'productversion', '(', ')' |
'filesize', '(', ')' |
'bitoffset', '(', node, ')' |
'byteoffset', '(', node, ')' |
'index', '(', node, ')' |
'index', '(', node, ',', boolexpr, ')' |
'if', '(', boolexpr, ',', intexpr, ',' intexpr, ')' |
'unboundindex', '(', node, ',', boolexpr, ')' |
'unboundindex', '(', node, ',', boolexpr, ',', boolexpr, ')' |
'at', '(', node, ',', intexpr, ')' |
'with', '(', indexvar, '=', intexpr, ',', intexpr, ')' ;
floatexpr =
floatvalue |
'nan' |
'inf' |
'float', '(', floatexpr, ')' |
'float', '(', node, ')' |
'float', '(', intexpr, ')' |
'float', '(', stringexpr, ')' |
'-', floatexpr |
'+', floatexpr |
floatexpr, '+', floatexpr |
floatexpr, '+', intexpr |
intexpr, '+', floatexpr |
floatexpr, '-', floatexpr |
floatexpr, '-', intexpr |
intexpr, '-', floatexpr |
floatexpr, '*', floatexpr |
floatexpr, '*', intexpr |
intexpr, '*', floatexpr |
floatexpr, '/', floatexpr |
floatexpr, '/', intexpr |
intexpr, '/', floatexpr |
floatexpr, '%', floatexpr |
floatexpr, '%', intexpr |
intexpr, '%', floatexpr |
floatexpr, '^', floatexpr |
floatexpr, '^', intexpr |
intexpr, '^', floatexpr |
intexpr, '^', intexpr |
'(', floatexpr, ')' |
'abs', '(', floatexpr, ')' |
'ceil', '(', floatexpr, ')' |
'floor', '(', floatexpr, ')' |
'round', '(', floatexpr, ')' |
'max', '(', node, ',', floatexpr, ')' |
'max', '(', floatexpr, ',', floatexpr, ')' |
'max', '(', floatexpr, ',', intexpr, ')' |
'max', '(', intexpr, ',', floatexpr, ')' |
'min', '(', node, ',', floatexpr, ')' |
'min', '(', floatexpr, ',', floatexpr, ')' |
'min', '(', floatexpr, ',', intexpr, ')' |
'min', '(', intexpr, ',', floatexpr, ')' |
'time', '(', stringepxr, ',', stringexpr, ')' |
'add', '(' node, ',', floatexpr, ')' |
'if', '(' boolexpr, ',', floatexpr, ',', floatexpr, ')' |
'if', '(' boolexpr, ',', floatexpr, ',', intexpr, ')' |
'if', '(' boolexpr, ',', intexpr, ',', floatexpr, ')' |
'with', '(', indexvar, '=', intexpr, ',', floatexpr, ')' ;
stringexpr =
stringvalue |
'r', stringvalue |
'str', '(', stringexpr, ')' |
'str', '(', node, ')' |
'str', '(', node, ',', intexpr, ')' |
'bytes', '(', node, ')' |
'bytes', '(', node, ',', intexpr, ')' |
'bytes', '(', node, ',', intexpr, ',', intexpr, ')' |
stringexpr, '+', stringexpr |
'substr', '(', intexpr, ',', intexpr, ',', stringexpr, ')' |
'ltrim', '(', stringexpr, ')' |
'rtrim', '(', stringexpr, ')' |
'trim', '(', stringexpr, ')' |
'add', '(', node, ',', stringexpr, ')' |
'max', '(', node, ',', stringexpr, ')' |
'max', '(', stringexpr, ',', stringexpr, ')' |
'min', '(', node, ',', stringexpr, ')' |
'min', '(', stringexpr, ',', stringexpr, ')' |
'regex', '(', stringexpr, ',', stringexpr, ',', intexpr ')' |
'regex', '(', stringexpr, ',', stringexpr, ',', stringexpr ')' |
'productformat', '(', ')' |
'productclass', '(', ')' |
'producttype', '(', ')' |
'filename', '(', ')' |
'strtime', '(', intexpr, ')' |
'strtime', '(', floatexpr, ')' |
'strtime', '(', intexpr, ',', stringexpr ')' |
'strtime', '(', floatexpr, ',', stringexpr ')' |
'if', '(' boolexpr, ',', stringexpr, ',', stringexpr, ')' |
'with', '(', indexvar, '=', intexpr, ',', stringexpr, ')' ;
rootnode = '/'
nonrootnode =
'.' |
':' |
'..' |
'asciiline' |
rootnode, identifier |
rootnode, '{', intexpr, '}' |
nonrootnode, '/..' |
nonrootnode, '/', identifier |
nonrootnode, '/', '{', intexpr, '}' |
'[', intexpr, ']' |
node, '[', intexpr, ']' |
'@', identifier |
'@', '{', intexpr, '}' |
node, '@', identifier |
node, '@', '{', intexpr, '}' ;
node =
rootnode |
nonrootnode ;
</pre></p>
<div class="footer">
<hr />
<p>Copyright © 2007-2022 <b>s<span class="soft-red">[</span>&<span class="soft-red">]</span>t</b>, The Netherlands.</p>
</div>
</div>
</body>
</html>
|