Skip to content

Latest commit

 

History

History
97 lines (93 loc) · 17.9 KB

FexScannerExt.md

File metadata and controls

97 lines (93 loc) · 17.9 KB

FexScanner Extensions

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

Comments:

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 Reference:

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.