Class SiemensExpressionParser
- Namespace
- Hi.NcParsers.EvaluationSyntaxs.Siemens
- Assembly
- HiMech.dll
Recursive-descent parser for Sinumerik value expressions. Produces the same NcExpr AST as the Fanuc NcExpressionParser so NcExpressionEvaluator is reused unchanged. Pure: no variable lookup, no evaluation.
Grammar (lowest precedence at top):
expr := or-expr
or-expr := and-expr (('OR' | 'XOR') and-expr)*
and-expr := cmp-expr ('AND' cmp-expr)*
cmp-expr := add-expr (('==' | '<>' | '>=' | '<=' | '>' | '<') add-expr)*
add-expr := term (('+' | '-') term)*
term := factor (('*' | '/' | 'MOD') factor)*
factor := ('+' | '-')? primary
primary := number
| '(' expr ')'
| 'R' digits → variable "R63" (canonical uppercase)
| '$' name ('[' indexlist ']')? → variable "$P_UIFR[1,X,TR]" (canonical)
| name '(' arglist ')' → function call
| name '[' indexlist ']' → variable "_RENC[35]" (canonical)
| name → variable "_X_HOME" (case preserved)
indexlist := (integer | name) (',' (integer | name))*
arglist := expr (',' expr)*
Dialect differences from the Fanuc parser: parentheses group and call
(Fanuc uses brackets); comparisons are spelled == <>
>= <= > < (Fanuc uses
EQ NE .. words); bare identifiers are named-variable references
(Fanuc rejects an identifier without [); R63 is
canonicalised to uppercase so table lookups and
Parsing.Assignments keys agree. Indexed accesses
($P_UIFR[1,X,TR], _RENC[35]) require literal index
elements (integers, bare letters, or keywords like TR) and are
emitted as a single NcVariableExpr whose key is the
canonical uppercase-indexed token — the whole token routes through
Get(string), keeping the AST brand-agnostic.
Function-name aliases are normalised where Sinumerik and the shared
evaluator spell the same math differently: ATAN2 → ATAN
(both are two-arg atan2 in degrees), TRUNC → FIX
(truncate toward zero). Unknown functions (e.g. the rotary positioning
form DC(...)) parse fine and fail later in the evaluator, which
callers treat as fail-soft.
public sealed class SiemensExpressionParser
- Inheritance
-
SiemensExpressionParser
- Inherited Members
- Extension Methods
Methods
TryParse(string, out NcExpr, out string)
Parses source requiring the whole string to be
consumed. On success, expr is the AST and
error is null. On failure,
expr is null and error
describes the syntax problem.
public static bool TryParse(string source, out NcExpr expr, out string error)
Parameters
Returns
TryParsePrefix(string, out NcExpr, out int, out string)
Parses the longest valid expression prefix of source.
On success, consumedLength is the number of leading
characters that form the expression (trailing text from that offset on
is the caller's to keep, e.g. as remaining UnparsedText).
Fails only when not even a prefix parses (e.g. the text starts with a
quote or an operator dangles at end-of-input) — callers fall back to
their legacy lexical capture in that case.
This is the parser-delimited RHS boundary: the expression grammar
itself decides where the right-hand side ends, so whitespace inside
expressions (R64 - 14/2), balanced call parentheses
(DC(47.296)) and a following non-expression word
(R24=14 R26=... / F=R103 X-204.) all resolve without
lexical boundary regexes or TerminateWords.
public static bool TryParsePrefix(string source, out NcExpr expr, out int consumedLength, out string error)