Skip to content

Commit 1447845

Browse files
authored
Merge pull request #10 from navtech-io/develop
Develop
2 parents 58f5927 + 0a9cde8 commit 1447845

16 files changed

+751
-485
lines changed

src/Simpleflow/CodeGenerator/SimpleflowErrorListener.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,15 @@ internal class SimpleflowErrorListener : BaseErrorListener
1616
public override void SyntaxError(TextWriter output, IRecognizer recognizer, IToken offendingSymbol, int line, int charPositionInLine,
1717
string msg, RecognitionException e)
1818
{
19-
Errors.Add(new SyntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e));
2019

21-
22-
//base.SyntaxError(output, recognizer, offendingSymbol, line, charPositionInLine, msg, e);
20+
if (recognizer.Atn.states[e.OffendingState].StateType == Antlr4.Runtime.Atn.StateType.BlockStart)
21+
{
22+
Errors.Add(new SyntaxError(recognizer, offendingSymbol, line, charPositionInLine, $"Unexpected token {offendingSymbol.Text}, a newline expected", e));
23+
}
24+
else
25+
{
26+
Errors.Add(new SyntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e));
27+
}
2328
}
2429

2530
public string GetAggregateMessages()

src/Simpleflow/Parser/Base/SimpleflowParserBase.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.IO;
55
using Antlr4.Runtime;
6+
using static Simpleflow.Parser.SimpleflowParser;
67

78
namespace Simpleflow.Parser
89
{
@@ -21,5 +22,41 @@ protected SimpleflowParserBase(ITokenStream input) : base(input)
2122
protected SimpleflowParserBase(ITokenStream input, TextWriter output, TextWriter errorOutput) : base(input, output, errorOutput)
2223
{
2324
}
25+
26+
27+
protected bool lineTerminatorAhead()
28+
{
29+
// Get the token ahead of the current index.
30+
int possibleIndexEosToken = CurrentToken.TokenIndex -1 ;
31+
IToken ahead = ((ITokenStream)this.InputStream).Get(possibleIndexEosToken);
32+
33+
if (ahead.Channel != Lexer.Hidden)
34+
{
35+
// We're only interested in tokens on the Hidden channel.
36+
return false;
37+
}
38+
39+
if (ahead.Type == LineTerminator)
40+
{
41+
// There is definitely a line terminator ahead.
42+
return true;
43+
}
44+
45+
if (ahead.Type == WhiteSpaces)
46+
{
47+
// Get the token ahead of the current whitespaces.
48+
possibleIndexEosToken = CurrentToken.TokenIndex - 2;
49+
ahead = ((ITokenStream)this.InputStream).Get(possibleIndexEosToken);
50+
}
51+
52+
// Get the token's text and type.
53+
string text = ahead.Text;
54+
int type = ahead.Type;
55+
56+
// Check if the token is, or contains a line terminator.
57+
return (type == MultiLineComment && (text.Contains("\r") || text.Contains("\n"))) ||
58+
(type == LineTerminator);
59+
}
60+
2461
}
2562
}

src/Simpleflow/Parser/Grammar/Simpleflow.g4

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,11 @@ options {
66
}
77

88
program
9-
:
10-
LineBreak*
11-
letStmt*
9+
: letStmt*
1210
(ruleStmt | generalStatement)* EOF;
1311

14-
1512
ruleStmt
16-
: Rule When predicate Then LineBreak
13+
: Rule When predicate Then eos
1714
( messageStmt
1815
| errorStmt
1916
| outputStmt
@@ -25,11 +22,11 @@ ruleStmt
2522
;
2623

2724
endRuleStmt
28-
: 'end' 'rule' LineBreak
25+
: 'end' 'rule' eos
2926
;
3027

3128
exitStmt
32-
: 'exit' LineBreak
29+
: 'exit' eos
3330
;
3431

3532
generalStatement
@@ -42,37 +39,42 @@ generalStatement
4239
;
4340

4441
letStmt
45-
: Let Identifier Assign expression LineBreak
42+
: Let Identifier Assign expression eos
4643
;
4744

4845
setStmt
49-
: (Partial)? Set Identifier Assign expression LineBreak
46+
: (Partial)? Set Identifier Assign expression eos
5047
;
5148

5249
messageStmt
53-
: Message messageText LineBreak
50+
: Message messageText eos
5451
;
5552

5653
errorStmt
57-
: Error messageText LineBreak
54+
: Error messageText eos
5855
;
5956

6057
messageText
6158
: (String | objectIdentifier)
6259
;
6360

6461
outputStmt
65-
: Output objectIdentifier LineBreak
62+
: Output objectIdentifier eos
6663
;
6764

6865
functionStmt
69-
: function LineBreak
66+
: function eos
7067
;
7168

7269
expression
7370
: boolLeteral | noneLiteral | function | jsonObj | arithmeticExpression | stringLiteral
7471
;
7572

73+
eos
74+
: EOF
75+
| {this.lineTerminatorAhead()}?
76+
;
77+
7678
// Lexer
7779

7880
Rule
@@ -101,15 +103,12 @@ Partial
101103
Assign
102104
: '=' ;
103105

104-
LineBreak
105-
: [\r\n]+[ \t\r\n]*
106-
;
106+
WhiteSpaces:
107+
[\t\u000B\u000C\u0020\u00A0]+ -> channel(HIDDEN);
107108

108-
Skip_
109-
: ( SPACES | COMMENT ) -> skip ;
109+
LineTerminator:
110+
[\r\n\u2028\u2029] -> channel(HIDDEN);
110111

111-
fragment SPACES
112-
: [ \t]+ ;
112+
MultiLineComment:
113+
'/*' .*? '*/' -> channel(HIDDEN);
113114

114-
fragment COMMENT
115-
: '/*' .*? '*/' ([\r\n]*) ;

src/Simpleflow/Parser/Simpleflow.interp

Lines changed: 6 additions & 3 deletions
Large diffs are not rendered by default.

src/Simpleflow/Parser/Simpleflow.tokens

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -17,30 +17,31 @@ Let=16
1717
Set=17
1818
Partial=18
1919
Assign=19
20-
LineBreak=20
21-
Skip_=21
22-
And=22
23-
Or=23
24-
Not=24
25-
GreaterThan=25
26-
GreaterThanEqual=26
27-
LessThan=27
28-
LessThanEqual=28
29-
Equal=29
30-
NotEqual=30
31-
Contains=31
32-
OpenParen=32
33-
CloseParen=33
34-
Number=34
35-
String=35
36-
None=36
37-
Identifier=37
38-
PlusOp=38
39-
MinusOp=39
40-
TimesOp=40
41-
DivOp=41
42-
ModuloOp=42
43-
FunctionName=43
20+
WhiteSpaces=20
21+
LineTerminator=21
22+
MultiLineComment=22
23+
And=23
24+
Or=24
25+
Not=25
26+
GreaterThan=26
27+
GreaterThanEqual=27
28+
LessThan=28
29+
LessThanEqual=29
30+
Equal=30
31+
NotEqual=31
32+
Contains=32
33+
OpenParen=33
34+
CloseParen=34
35+
Number=35
36+
String=36
37+
None=37
38+
Identifier=38
39+
PlusOp=39
40+
MinusOp=40
41+
TimesOp=41
42+
DivOp=42
43+
ModuloOp=43
44+
FunctionName=44
4445
'end'=1
4546
'exit'=2
4647
'.'=3
@@ -60,21 +61,21 @@ FunctionName=43
6061
'set'=17
6162
'partial'=18
6263
'='=19
63-
'and'=22
64-
'or'=23
65-
'not'=24
66-
'>'=25
67-
'>='=26
68-
'<'=27
69-
'<='=28
70-
'=='=29
71-
'!='=30
72-
'contains'=31
73-
'('=32
74-
')'=33
75-
'none'=36
76-
'+'=38
77-
'-'=39
78-
'*'=40
79-
'/'=41
80-
'%'=42
64+
'and'=23
65+
'or'=24
66+
'not'=25
67+
'>'=26
68+
'>='=27
69+
'<'=28
70+
'<='=29
71+
'=='=30
72+
'!='=31
73+
'contains'=32
74+
'('=33
75+
')'=34
76+
'none'=37
77+
'+'=39
78+
'-'=40
79+
'*'=41
80+
'/'=42
81+
'%'=43

src/Simpleflow/Parser/SimpleflowBaseListener.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,18 @@ public virtual void EnterExpression([NotNull] SimpleflowParser.ExpressionContext
193193
/// <param name="context">The parse tree.</param>
194194
public virtual void ExitExpression([NotNull] SimpleflowParser.ExpressionContext context) { }
195195
/// <summary>
196+
/// Enter a parse tree produced by <see cref="SimpleflowParser.eos"/>.
197+
/// <para>The default implementation does nothing.</para>
198+
/// </summary>
199+
/// <param name="context">The parse tree.</param>
200+
public virtual void EnterEos([NotNull] SimpleflowParser.EosContext context) { }
201+
/// <summary>
202+
/// Exit a parse tree produced by <see cref="SimpleflowParser.eos"/>.
203+
/// <para>The default implementation does nothing.</para>
204+
/// </summary>
205+
/// <param name="context">The parse tree.</param>
206+
public virtual void ExitEos([NotNull] SimpleflowParser.EosContext context) { }
207+
/// <summary>
196208
/// Enter a parse tree produced by <see cref="SimpleflowParser.predicate"/>.
197209
/// <para>The default implementation does nothing.</para>
198210
/// </summary>

src/Simpleflow/Parser/SimpleflowBaseVisitor.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,16 @@ internal partial class SimpleflowBaseVisitor<Result> : AbstractParseTreeVisitor<
166166
/// <return>The visitor result.</return>
167167
public virtual Result VisitExpression([NotNull] SimpleflowParser.ExpressionContext context) { return VisitChildren(context); }
168168
/// <summary>
169+
/// Visit a parse tree produced by <see cref="SimpleflowParser.eos"/>.
170+
/// <para>
171+
/// The default implementation returns the result of calling <see cref="AbstractParseTreeVisitor{Result}.VisitChildren(IRuleNode)"/>
172+
/// on <paramref name="context"/>.
173+
/// </para>
174+
/// </summary>
175+
/// <param name="context">The parse tree.</param>
176+
/// <return>The visitor result.</return>
177+
public virtual Result VisitEos([NotNull] SimpleflowParser.EosContext context) { return VisitChildren(context); }
178+
/// <summary>
169179
/// Visit a parse tree produced by <see cref="SimpleflowParser.predicate"/>.
170180
/// <para>
171181
/// The default implementation returns the result of calling <see cref="AbstractParseTreeVisitor{Result}.VisitChildren(IRuleNode)"/>

0 commit comments

Comments
 (0)