Skip to content

Commit 67d66a8

Browse files
committed
Upgraded to use Scanners v1.1.0 with configurable comments.
1 parent 8bc5d7a commit 67d66a8

File tree

5 files changed

+76
-21
lines changed

5 files changed

+76
-21
lines changed

Docs/FexScannerExt.md

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,32 @@ to add Op(operators) and other methods bound to FexScanner (i.e. the Context).
66

77
> **Note:** Several methods record the scanned text in Token (of the underlying scanner)
88
> and can be accessed via:
9-
> - ActToken / ActTrimToken / ActStripToken / ActTrimStripToken.
10-
> - Act(c => c.Token...).
9+
> - `ActToken / ActTrimToken / ActStripToken / ActTrimStripToken`.
10+
> - `Act(c => c.Token...)`.
1111
1212
Basic extension example:
1313
```csharp
1414
public static FexBuilder<T> Ch<T>(this FexBuilder<T> exp, char ch) where T : FexScanner
1515
=> exp.Op(o => o.IsCh(ch)); // IsCh is a FexScanner method
1616
```
17-
<br/>
18-
19-
**Extensions Reference:**
17+
---
18+
### Comments:
19+
FexScanner can skip line and block comments via `SkipWSC`:
20+
- Default line comment starts with `//`.
21+
- Default block comment `/* ... */`.
22+
- These comments can be configured (or switched off) via the `FexScanner.ConfigComments(...)` method.
23+
```csharp
24+
// Set comment configuration:
25+
// - For block comments Start and End must both be valid to enable block comments.
26+
//
27+
// lineComment: Line comment (null/empty for none).
28+
// blockCommentStart: Block comment start (null/empty for none).
29+
// blockCommentEnd: Block comment end (null/empty for none).
30+
// Returns: FexScanner for fluent chaining.
31+
public FexScanner ConfigComment(string lineComment = "//", string blockCommentStart = "/*", string blockCommentEnd = "*/")
32+
```
33+
---
34+
### Extensions Reference:
2035

2136
| Extensions | Description |
2237
| :---- | :------ |
@@ -75,7 +90,7 @@ public static FexBuilder<T> Ch<T>(this FexBuilder<T> exp, char ch) where T : Fex
7590
| ***Whitespace and Comment Skipping:*** | |
7691
| ``E: OptSp(string spaceChars = " \t")`` | Optionally skip given space characters (default = " \t") - creates optional (Opt) Op.<br/> |
7792
| ``E: SkipWS(string wsChars = " \r\n\t", bool opt = false)`` | Skip given White Space characters (default: " \r\n\t").<br/><br/>**Parameters:**<br/><code>opt:</code> Make the Op optional or not.<br/><br/>**Returns:**<br/>True if not at Eos after skipping or opt == true else False. |
78-
| ``E: SkipWSC(bool termNL = false, string spaceChars = " \t", bool opt = false)`` | Skip given space characters (default = " \t"), newlines (if termNL = false) and comments //... or /\*..\*/ (handles nested comments):<br/>- White space: spaceChars + "\r\n" if termNL is false.<br/>- Set termNL to position Index at the next newline not inside a block comment (/\*..\*/), else the newlines are also skipped.<br/><br/>**Parameters:**<br/><code>opt:</code> Make the Op optional or not.<br/><br/>**Returns:**<br/>True: Whitespace and comments skipped and Index directly after, or no comment error and opt == true.<br/> False: Eos or comment error (bad comment error is Logged. Use IsScanError() to check) - Index unchanged. |
93+
| ``E: SkipWSC(bool termNL = false, string spaceChars = " \t", bool opt = false)`` | Skip White Space and comments:<br/>- White space: spaceChars + "\r\n" if termNL is false.<br/>- Block comments handle nesting and comments embedded in delimited strings.<br/>- Set termNL to true to stop at a newline, including the newline at the end of a line comment.<br/><br/>**Parameters:**<br/><code>termNL:</code> True to stop at a newline, including the newline at the end of a line comment.<br/><code>spaceChars:</code> Characters to regard as white-space (default: " \t").<br/><code>opt:</code> Make the Op optional or not.<br/><br/>**Returns:**<br/>True: Whitespace and comments skipped and Index directly after, or no comment error and opt == true.<br/> False: Eos or comment error (bad comment error is Logged. Use IsScanError() to check) - Index unchanged. |
7994
| ``E: Sp(string spaceChars = " \t")`` | Skip given space characters (default = " \t").<br/><br/>**Returns:**<br/>True if not at Eos after skipping else False. |
8095
| ***Error Messages:*** | |
8196
| ``E: OnFail(string errorMsg, string errorSource = "Parse error")`` | For convenience, bind OnFail to ErrorLog.<br/> |

FexSampleSet/Program.cs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -364,20 +364,28 @@ void ExpressionREPL() {
364364

365365
Stack<double> numStack = new Stack<double>();
366366

367+
void OpPush(Func<double, double, double> op)
368+
=> numStack.Push(op(numStack.Pop(), numStack.Pop()));
369+
367370
var expr = fex.Seq(s => s
368371
.Ref("factor")
369372
.RepOneOf(0, -1, r => r
370-
.Seq(s => s.Ch('+').Ref("factor").Act(c => numStack.Push(numStack.Pop() + numStack.Pop())))
371-
.Seq(s => s.Ch('-').Ref("factor").Act(c => numStack.Push(-numStack.Pop() + numStack.Pop())))
373+
//.Seq(s => s.Ch('+').Ref("factor").Act(c => numStack.Push(numStack.Pop() + numStack.Pop())))
374+
.Seq(s => s.Ch('+').Ref("factor").Act(c => OpPush((s0, s1) => s0 + s1)))
375+
//.Seq(s => s.Ch('-').Ref("factor").Act(c => numStack.Push(-numStack.Pop() + numStack.Pop())))
376+
.Seq(s => s.Ch('-').Ref("factor").Act(c => OpPush((s0, s1) => s1 - s0)))
372377
));
373378

374379
var factor = fex.Seq(s => s.RefName("factor")
375380
.Ref("unary")
376381
.RepOneOf(0, -1, r => r
377-
.Seq(s => s.Ch('*').Ref("unary").Act(c => numStack.Push(numStack.Pop() * numStack.Pop())))
382+
//.Seq(s => s.Ch('*').Ref("unary").Act(c => numStack.Push(numStack.Pop() * numStack.Pop())))
383+
.Seq(s => s.Ch('*').Ref("unary").Act(c => OpPush((s0, s1) => s0 * s1)))
384+
.Seq(s => s.Ch('^').Ref("unary").Act(c => OpPush((s0, s1) => Math.Pow(s1, s0))))
378385
.Seq(s => s.Ch('/').Ref("unary")
379386
.Op(c => numStack.Peek() != 0).OnFail("Division by 0") // Trap division by 0
380-
.Act(c => numStack.Push(1 / numStack.Pop() * numStack.Pop())))
387+
//.Act(c => numStack.Push(1 / numStack.Pop() * numStack.Pop())))
388+
.Act(c => OpPush((s0, s1) => s1 / s0)))
381389
));
382390

383391
var unary = fex.Seq(s => s.RefName("unary")
@@ -389,8 +397,9 @@ void ExpressionREPL() {
389397
var primary = fex.Seq(s => s.RefName("primary")
390398
.OneOf(o => o
391399
.Seq(e => e.Ch('(').Fex(expr).Ch(')').OnFail(") expected"))
392-
.Seq(s => s.NumDecimal(n => numStack.Push(n)))
400+
.Seq(s => s.IsString("pi").Act(c => numStack.Push(Math.PI))) // Pi
393401
.Seq(s => s.Ch('a').Act(c => numStack.Push(ans))) // a is previous answer
402+
.Seq(s => s.NumDecimal(n => numStack.Push(n)))
394403
).OnFail("Primary expected"));
395404

396405
var exprEval = fex.Seq(s => s.GlobalPreOp(c => c.SkipSp()).Fex(expr).IsEos().OnFail("invalid expression"));

Psw.FlowExpressions/FexScanner.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,18 @@ namespace Psw.FlowExpressions
1515
public class FexScanner : ScriptScanner
1616
{
1717
public FexScanner(string source = "", ScanErrorLog errorLog = null) : base(source, errorLog) { }
18+
19+
/// <summary>
20+
/// Set comment configuration:<br/>
21+
/// - For block comments Start and End must both be valid to enable block comments.
22+
/// </summary>
23+
/// <param name="lineComment">Line comment (null/empty for none).</param>
24+
/// <param name="blockCommentStart">Block comment start (null/empty for none).</param>
25+
/// <param name="blockCommentEnd">Block comment end (null/empty for none).</param>
26+
/// <returns>FexScanner for fluent chaining.</returns>
27+
public FexScanner ConfigComment(string lineComment = "//", string blockCommentStart = "/*", string blockCommentEnd = "*/") {
28+
SetScriptComment(lineComment, blockCommentStart, blockCommentEnd);
29+
return this; ;
30+
}
1831
}
1932
}

Psw.FlowExpressions/FexScannerExt.cs

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,32 @@ namespace Psw.FlowExpressions
1717
///
1818
/// > **Note:** Several methods record the scanned text in Token (of the underlying scanner)
1919
/// > and can be accessed via:
20-
/// > - ActToken / ActTrimToken / ActStripToken / ActTrimStripToken.
21-
/// > - Act(c => c.Token...).
20+
/// > - `ActToken / ActTrimToken / ActStripToken / ActTrimStripToken`.
21+
/// > - `Act(c => c.Token...)`.
2222
///
2323
/// Basic extension example:
2424
/// ```csharp
2525
/// public static FexBuilder<T> Ch<T>(this FexBuilder<T> exp, char ch) where T : FexScanner
2626
/// => exp.Op(o => o.IsCh(ch)); // IsCh is a FexScanner method
2727
/// ```
28-
/// <br/>
29-
///
30-
/// **Extensions Reference:**
28+
/// ---
29+
/// ### Comments:
30+
/// FexScanner can skip line and block comments via `SkipWSC`:
31+
/// - Default line comment starts with `//`.
32+
/// - Default block comment `/* ... */`.
33+
/// - These comments can be configured (or switched off) via the `FexScanner.ConfigComments(...)` method.
34+
/// ```csharp
35+
/// // Set comment configuration:
36+
/// // - For block comments Start and End must both be valid to enable block comments.
37+
/// //
38+
/// // lineComment: Line comment (null/empty for none).
39+
/// // blockCommentStart: Block comment start (null/empty for none).
40+
/// // blockCommentEnd: Block comment end (null/empty for none).
41+
/// // Returns: FexScanner for fluent chaining.
42+
/// public FexScanner ConfigComment(string lineComment = "//", string blockCommentStart = "/*", string blockCommentEnd = "*/")
43+
/// ```
44+
/// ---
45+
/// ### Extensions Reference:
3146
/// </mdoc>
3247
public static class FexScannerExt
3348
{
@@ -505,10 +520,13 @@ public static FexBuilder<T> SkipWS<T>(this FexBuilder<T> exp, string wsChars = "
505520
=> exp.Op(c => c.SkipWS(wsChars) || opt);
506521

507522
/// <summary>
508-
/// Skip given space characters (default = " \t"), newlines (if termNL = false) and comments //... or /*..*/ (handles nested comments):<br/>
523+
/// Skip White Space and comments:<br/>
509524
/// - White space: spaceChars + "\r\n" if termNL is false.<br/>
510-
/// - Set termNL to position Index at the next newline not inside a block comment (/*..*/), else the newlines are also skipped.
525+
/// - Block comments handle nesting and comments embedded in delimited strings.<br/>
526+
/// - Set termNL to true to stop at a newline, including the newline at the end of a line comment.
511527
/// </summary>
528+
/// <param name="termNL">True to stop at a newline, including the newline at the end of a line comment.</param>
529+
/// <param name="spaceChars">Characters to regard as white-space (default: " \t").</param>
512530
/// <param name="opt">Make the Op optional or not.</param>
513531
/// <returns>
514532
/// True: Whitespace and comments skipped and Index directly after, or no comment error and opt == true.<br/>

Psw.FlowExpressions/Psw.FlowExpressions.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@
1313
<PackageProjectUrl>https://github.com/promicsw/flow-expressions</PackageProjectUrl>
1414
<RepositoryUrl>https://github.com/promicsw/flow-expressions</RepositoryUrl>
1515
<PackageTags>parser;parser-builder;flow-logic;c#;flow-expression;</PackageTags>
16-
<PackageReleaseNotes>Skip feature added for common skipping actions during parsing.</PackageReleaseNotes>
16+
<PackageReleaseNotes>Upgraded to use Scanners v1.1.0 which has configurable comments.</PackageReleaseNotes>
1717
<PackageLicenseExpression>MIT</PackageLicenseExpression>
1818
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
1919
<PackageReadmeFile>Nuget.md</PackageReadmeFile>
2020
<PackageOutputPath>d:\PromicSW_GitHub\LocalNuget\</PackageOutputPath>
2121
<PackageIcon>PswLogo.png</PackageIcon>
22-
<Version>1.0.1</Version>
22+
<Version>1.0.2</Version>
2323
</PropertyGroup>
2424

2525
<ItemGroup>
@@ -38,7 +38,7 @@
3838
</ItemGroup>
3939

4040
<ItemGroup>
41-
<PackageReference Include="Psw.Scanners" Version="1.0.3" />
41+
<PackageReference Include="Psw.Scanners" Version="1.1.0" />
4242
</ItemGroup>
4343

4444
</Project>

0 commit comments

Comments
 (0)