Consider a grammar with an LR state machine containing the following state:
State M:
(EOF) Reduce Production <P> ::=
<P> Goto State M
If Farkle encounters EOF while in state M, the parser would keep reducing and infinitely loop:
|
RetryEof: |
|
LrEndOfFileAction eofAction = _lrStateMachine.GetEndOfFileAction(currentState); |
|
if (eofAction.IsAccept) |
|
{ |
|
result = semanticValueStack.Peek(); |
|
return RunResult.Success; |
|
} |
|
if (eofAction.IsReduce) |
|
{ |
|
try |
|
{ |
|
currentState = Reduce(ref input, in hotData, ref stateStack, ref semanticValueStack, eofAction.ReduceProduction); |
|
} |
|
catch (ParserApplicationException ex) |
|
{ |
|
result = ex.GetErrorObject(input.State.CurrentPosition); |
|
return RunResult.Failure; |
|
} |
|
goto RetryEof; |
|
} |
More non-trivial states can also cause the parser to loop. The builder won't emit such state machine, but a grammar from a specially crafted file could.
Not critical for 7.0.
Consider a grammar with an LR state machine containing the following state:
If Farkle encounters EOF while in state M, the parser would keep reducing and infinitely loop:
Farkle/src/Farkle/Parser/Implementation/DefaultParserImplementation.cs
Lines 78 to 97 in 1e5a4fe
More non-trivial states can also cause the parser to loop. The builder won't emit such state machine, but a grammar from a specially crafted file could.
Not critical for 7.0.