FlowExpressions Context Operator Extensions for FexScanner (FexScanner is an alias for ScriptScanner).
These extend FexBuilder<T> (where T is FexScanner) to add Op(operators) and other methods bound to FexScanner (i.e. the Context).
Note: Several methods record the scanned text in Token (of the underlying scanner) and can be accessed via:
ActToken / ActTrimToken / ActStripToken / ActTrimStripToken
.Act(c => c.Token...)
.
Basic extension example:
public static FexBuilder<T> Ch<T>(this FexBuilder<T> exp, char ch) where T : FexScanner
=> exp.Op(o => o.IsCh(ch)); // IsCh is a FexScanner method
FexScanner can skip line and block comments via SkipWSC
:
- Default line comment starts with
//
. - Default block comment
/* ... */
. - These comments can be configured (or switched off) via the
FexScanner.ConfigComments(...)
method.
// Set comment configuration:
// - For block comments Start and End must both be valid to enable block comments.
//
// lineComment: Line comment (null/empty for none).
// blockCommentStart: Block comment start (null/empty for none).
// blockCommentEnd: Block comment end (null/empty for none).
// Returns: FexScanner for fluent chaining.
public FexScanner ConfigComment(string lineComment = "//", string blockCommentStart = "/*", string blockCommentEnd = "*/")
Extensions | Description |
---|---|
Token Actions: | |
E: ActStripToken(Action<string> actToken) |
Perform an Action (Act) with the current Token stripped of all comments. |
E: ActToken(Action<string> actToken) |
Perform an Action (Act) with the current Token. |
E: ActTrimStripToken(Action<string> actToken) |
Perform an Action (Act) with the current Token trimmed and stripped of all comments. |
E: ActTrimToken(Action<string> actToken) |
Perform an Action (Act) with the current Trimmed Token. |
E: ValidToken() |
Check if the current Token is not null or WhiteSpace. |
Core Utilities: | |
E: AnyCh(string matchChars, Action<char>? valueAction = null) |
Check if character at Index is one of the matchChars: - Optionally perform an action on the character. Returns: True: if found, advances the Index and logs the char in Delim and Value. False: if not found and Index is unchanged. |
E: Ch(char ch) |
Check if the character at Index matches ch and advance Index if it does. |
E: IsAnyString(IEnumerable<string> matchStrings, bool advanceIndex = true, StringComparison comp = StringComparison.InvariantCultureIgnoreCase) |
Check if text at Index equals any string in matchString and optionally advance Index if it matches. Parameters: matchStrings: Enumerable set of strings.advanceIndex: Advance Index to just after match (default) else not.comp: Comparison type (default = StringComparison.InvariantCultureIgnoreCase).Returns: True and matching string is logged in Match and Value, else false. |
E: IsAnyString(string matchStrings, bool advanceIndex = true, StringComparison comp = StringComparison.InvariantCultureIgnoreCase) |
Check if text at Index equals any string in delimited matchStrings and optionally advance the Index if it matches. Parameters: matchStrings: Delimited strings and first character must be the delimiter (e.g. "|s1|s2|...").advanceIndex: Advance Index to just after match (default) else not.comp: Comparison type (default = StringComparison.InvariantCultureIgnoreCase)Returns: True and matching string is logged in Match and Value, else false. |
E: IsDelim(char delim) |
Check if the last Delim matches delim (for methods that log a Delim). |
E: IsEol() |
Query if Index is at End-of-Line. |
E: IsEos() |
Query if Index is at End-of-Source. |
E: IsMatch(string matchString, StringComparison comp = StringComparison.InvariantCultureIgnoreCase) |
Check if the last Match matches matchString (for methods that log a Match). Parameters: matchString: String to match.comp: Comparison type (default = StringComparison.InvariantCultureIgnoreCase). |
E: IsString(string matchString, bool advanceIndex = true, StringComparison comp = StringComparison.InvariantCultureIgnoreCase) |
Check if text at Index equals matchString and optionally advance Index if it matches. Parameters: comp: Comparison type (default = StringComparison.InvariantCultureIgnoreCase) |
E: PeekAnyCh(string matchChars, int offset = 0) |
Check if character at relative offset to Index matches any one of the matchChars (index unchanged). |
E: PeekCh(char ch, int offset = 0) |
Check if character at relative offset to Index matches ch (index unchanged). |
Skipping Operations: | |
E: Skip(char skipChar) |
Skip while character is skipChar. Returns: True if not Eos after skipping else false. |
E: SkipAny(string skipChars) |
Skip while character is any of the skipChars. Returns: True if not Eos after skipping else false. |
E: SkipTo(char termChar, bool skipOver = false) |
Skip until the termChar is found: - Optionally skip over the delimiter if skipOver is true. Returns: True: Found and Index at matching char or next if skipOver = true. False: Not found or Eos. Index not changed. |
E: SkipToAny(string termChars, bool skipOver = false) |
Skip until any one of the termChars is found, which is logged in Delim and Value: - Optionally skip over the delimiter if skipOver is true. Returns: True: Found and Index at matching char or next if skipOver = true False: Not found or Eos. Index not changed. |
E: SkipToStr(string str, bool skipOver = false) |
Skip up to given str and optionally skip over it if skipOver is true. Returns: True: Found and Index at matching start of text or just after if skipOver = true. False: Not found or Eos. Index not changed. |
E: SkipToAnyStr(IEnumerable<string> matchStrings, bool skipOver = false, StringComparison comp = StringComparison.InvariantCultureIgnoreCase) |
Skip up to first occurrence of any string in matchStrings and optionally skip over the matching string: - The matching string is logged in Match and Value. Parameters: matchStrings: Enumerable set of strings.skipOver: Advance Index to just after match (default = false) else not.comp: Comparison type (default = StringComparison.InvariantCultureIgnoreCase).Returns: True: Found and Index at start of matching text or just after if skipOver = true. False: Not found or Eos. Index unchanged. |
E: SkipToAnyStr(string matchStrings, bool skipOver = false, StringComparison comp = StringComparison.InvariantCultureIgnoreCase) |
Skip up to first occurrence of any string in delimited matchStrings and optionally skip over the matching string: - The matching string is logged in Match and Value. Parameters: matchStrings: Delimited string and first character must be the delimiter (e.g. "|s1|s2|...").skipOver: Advance Index to just after match (default = false) else not.comp: Comparison type (default = StringComparison.InvariantCultureIgnoreCase).Returns: True: Found and Index at start of matching text or just after if skipOver = true. False: Not found or Eos. Index unchanged. |
E: SkipToEol(bool skipOver = true) |
Skip to Eol or Eos (last line): - Optionally skip over the Eol if skipOver is true. Returns: False if started at Eos else True. |
E: SkipEol() |
Skip one NewLine - must currently be at the newline (else the operation is ignored). Returns: True if not Eos after skipping else false. |
E: SkipConsecEol() |
Skip All consecutive NewLines - must currently be at a newline (else the operation is ignored). Returns: True if not Eos after skipping else false. |
E: SkipWhile(Func<char, bool> predicate) |
Skip all characters while a predicate matches. |
E: SkipBlock(string blockStart, string blockEnd, bool isOpen = false) |
Skip a block delimited by blockStart and blockEnd: - Handles Nesting. Parameters: isOpen: False - current Index at start of block else Index just inside block.Returns: True if not at the start of a non-open block or for a valid block (Index positioned after block). Else false and Logs an error (Index unchanged). |
Scanning Operations: | |
E: ScanTo(char delim, bool orToEos = false, bool skipOver = false) |
Scans up to the delim or to Eos (if orToEos it true): - Optionally skip over the delimiter if skipOver is true. - Token contains the intermediate text (excluding delimiter). Returns: True: Delimiter found or orToEos is true. Index at Eos, delimiter or after delimiter if skipOver False: Started at Eos or delimiter not found (and orToEos is false). Index unchanged. |
E: ScanToAny(string delims, bool orToEos = false) |
Scans up to any character in delims or to Eos (if orToEos it true): - Token contains the intermediate text (excluding delimiter). - The terminating delimiter is logged in Delim and Value. Returns: True: Delimiter found or orToEos is true. Index at delimiter or Eos. False: Started at Eos, delimiter not found (and orToEos is false) or delims is blank. Index unchanged. |
E: ScanToStr(string findString, StringComparison comp = StringComparison.InvariantCultureIgnoreCase) |
Scan up to a match of findString: - Token contains the intermediate text (excluding findString). Parameters: comp: Comparison type (default = StringComparison.InvariantCultureIgnoreCase).Returns: True: findString found and Index directly after findString False: findString not found and Index remains at original position. |
E: ScanToAnyStr(IEnumerable<string> matchStrings, bool skipOver = false, StringComparison comp = StringComparison.InvariantCultureIgnoreCase) |
Scan up to first occurrence of any string in matchStrings. - Token contains the intermediate text (excluding matching string) - The matching string is logged in Match and Value. Parameters: matchStrings: Enumerable set of strings.skipOver: Advance Index to just after match (default = false) else not.comp: Comparison type (default = StringComparison.InvariantCultureIgnoreCase).Returns: True: Found and Index at start of matching text or just after if skipOver = true. False: Not found or Eos. Index unchanged. |
E: ScanToAnyStr(string matchStrings, bool skipOver = false, StringComparison comp = StringComparison.InvariantCultureIgnoreCase) |
Scan up to first occurrence of any string in delimited matchStrings. - Token contains the intermediate text (excluding matching string). - The matching string is logged in Match and Value. Parameters: matchStrings: Delimited string and first character must be the delimiter (e.g. "|s1|s2|...").skipOver: Advance Index to just after match (default = false) else not.comp: Comparison type (default = StringComparison.InvariantCultureIgnoreCase).Returns: True: Found and Index at start of matching text or just after if skipOver = true. False: Not found or Eos. Index unchanged. |
E: ScanToEol(bool skipEol = true) |
Scan to Eol and optionally skip over Eol: - Handles intermediate or last line (with no Eol). - Token contains the intermediate text (excluding the newline). Returns: False if started at Eos else true. |
E: ValueToEol(bool skipEol = true) |
Scan a value (token) to Eol and optionally skip over Eol: - Handles intermediate or last line (with no Eol). - Token contains the intermediate text (excluding the newline). Returns: False if started at Eos or a non-valid Token else true. |
E: ScanWhile(Func<TextScanner, char, int, bool> predicate) |
Scan all characters while a predicate matches: - Predicate = Func<current char, index from starting position, bool> - Token contains the scanned characters string. Returns: True if any characters are scanned (Index after last match) else false (Index unchanged) |
Type Operations: | |
E: Digit(Action<char>? valueAction = null) |
Scan a digit character and perform valueAction on it if valid, else fails. |
E: NumDecimal(Action<double>? valueAction = null) |
Scan a Decimal value and perform valueAction on it if valid, else fails. |
E: NumInt(Action<int>? valueAction = null) |
Scan an Integer value and perform valueAction on it if valid, else fails. |
Script Scanning: | |
E: ScanBlock(string blockDelims = "{}", bool isOpen = false) |
Scan a block delimited by blockDelims E.g "{}" or "()" or "[]" etc: - Handles Nesting and ignores any block delimiters inside comments or strings (delimited by StringDelim). - Token contains the block content excluding the block delimiters. Parameters: blockDelims: String with opening and closing delimiter (default = "{}).isOpen: Current Index at start of block (false) else inside block.Returns: True for a valid block (Index after block) else false and Logs an error (Index unchanged). |
E: ScanList(string delims = "()", char separator = ',', string block = "[]") |
Scan a List of the form: ( item1, item 2 ... ): - Note: The next non-whitespace character must be the Opening list delimiter. - Item type 1: All text up to next closing delim or separator (logged trimmed). - Item type 2: A string literal - may NOT span a line! (logged verbatim excluding string delimiters). - Item type 3: Block delimited text (logged verbatim excluding block delimiters) - use for multi-line text. - Blank items are not recorded. Parameters: delims: Opening and closing list delimiter (default = "()").separator: List item separator (default = ,).block: Opening an closing Block delimiters (default = "[]").Returns: True and List of strings is logged as a value, else false and error logged in ErrorLog. |
E: StdIdent(Action<string> actIdent) |
Scan Standard Identifier of the form: (letter | _)* (letterordigit | _)*: - Then perform an action on the identifier if valid. Parameters: actIdent: Action to perform on the valid identifier (or null for no action).Returns: True for valid identifier (and performs action) else false. |
E: StdIdent2(Action<string> actIdent) |
Scan Standard Identifier of the form: (letter | _)* (letterordigit | _ | -)*: - Then perform an action on the identifier if valid. Parameters: actIdent: Action to perform on the valid identifier (or null for no action).Returns: True for valid identifier (and performs action) else false. |
E: StringDelim() |
Check if current character is a string delimiter (as set in FexScanner) |
E: StrLit() |
Scan a delimited String Literal: - Current Index must be at the starting delimiter ("`' etc). - Token contains the string (excluding delimiters). Returns: True: if there was a string literal and Index positioned after ending delimiter. False: for no string or Eos - Index unchanged. |
E: ValueOrStrLit(string termChars, bool orToEos = false) |
Scan either a StrLit or result of ScanTo(termChars, orToEos): - If Index is at a StringDelim - returns the result of StrLit(). - Else returns the result of ScanTo(termChars, orToEos). - Token contains the value. Returns: Success of the scan. |
Whitespace and Comment Skipping: | |
E: OptSp(string spaceChars = " \t") |
Optionally skip given space characters (default = " \t") - creates optional (Opt) Op. |
E: SkipWS(string wsChars = " \r\n\t", bool opt = false) |
Skip given White Space characters (default: " \r\n\t"). Parameters: opt: Make the Op optional or not.Returns: True if not at Eos after skipping or opt == true else False. |
E: SkipWSC(bool termNL = false, string spaceChars = " \t", bool opt = false) |
Skip White Space and comments: - White space: spaceChars + "\r\n" if termNL is false. - Block comments handle nesting and comments embedded in delimited strings. - Set termNL to true to stop at a newline, including the newline at the end of a line comment. Parameters: termNL: True to stop at a newline, including the newline at the end of a line comment.spaceChars: Characters to regard as white-space (default: " \t").opt: Make the Op optional or not.Returns: True: Whitespace and comments skipped and Index directly after, or no comment error and opt == true. False: Eos or comment error (bad comment error is Logged. Use IsScanError() to check) - Index unchanged. |
E: Sp(string spaceChars = " \t") |
Skip given space characters (default = " \t"). Returns: True if not at Eos after skipping else False. |
Error Messages: | |
E: OnFail(string errorMsg, string errorSource = "Parse error") |
For convenience, bind OnFail to ErrorLog. |
E: Fail(string errorMsg, string errorSource = "Parse error") |
For convenience, bind Fail to ErrorLog. |