Skip to content

Commit

Permalink
Push the initial state to the LR parser stack.
Browse files Browse the repository at this point in the history
Turns out it is always needed to do GOTOs from the initial state if we reduce a production with as many members as the stack.
And with that we don't need to separately track the LR state anymore; it's at the top of the stack.
  • Loading branch information
teo-tsirpanis committed Aug 29, 2023
1 parent 3958c81 commit 112e674
Showing 1 changed file with 15 additions and 8 deletions.
23 changes: 15 additions & 8 deletions src/FarkleNeo/Parser/Implementation/DefaultParserImplementation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ private void Reduce(ref ParserInputReader<TChar> input, ref int currentState, re
currentState = gotoState;
}

private RunResult Run(ref ParserInputReader<TChar> input, ref int currentState, ref ValueStack<int> stateStack, ref ValueStack<object?> semanticValueStack, out object? result)
private RunResult Run(ref ParserInputReader<TChar> input, ref ValueStack<int> stateStack, ref ValueStack<object?> semanticValueStack, out object? result)
{
int currentState = stateStack.Peek();
bool foundToken = Tokenizer.TryGetNextToken(ref input, TokenSemanticProvider, out TokenizerResult token);
while (true)
{
Expand Down Expand Up @@ -117,9 +118,10 @@ private unsafe void RunOneShot<T>(ref ParserInputReader<TChar> input, ref Parser
{
ValueStack<int> stateStack = new(stackalloc int[InitialStackCapacity]);
ValueStack<object?> semanticValueStack = new(InitialStackCapacity);
int currentState = _lrStateMachine.InitialState;
stateStack.Push(_lrStateMachine.InitialState);
semanticValueStack.Push(null);
#pragma warning disable CS9080 // Use of variable in this context may expose referenced variables outside of their declaration scope
RunResult runResult = Run(ref input, ref currentState, ref stateStack, ref semanticValueStack, out object? result);
RunResult runResult = Run(ref input, ref stateStack, ref semanticValueStack, out object? result);
#pragma warning restore CS9080 // Use of variable in this context may expose referenced variables outside of their declaration scope
switch (runResult)
{
Expand All @@ -145,7 +147,7 @@ public void Run<T>(ref ParserInputReader<TChar> input, ref ParserCompletionState
var semanticValueStack = new ValueStack<object?>(state.SemanticValueStack);
try
{
RunResult result = Run(ref input, ref state.CurrentState, ref stateStack, ref semanticValueStack, out object? runResult);
RunResult result = Run(ref input, ref stateStack, ref semanticValueStack, out object? runResult);
switch (result)
{
case RunResult.Success:
Expand Down Expand Up @@ -173,7 +175,6 @@ private enum RunResult

private sealed class State
{
public int CurrentState;
public ValueStack<int>.State StateStack;
public ValueStack<object?>.State SemanticValueStack;

Expand All @@ -183,13 +184,19 @@ public static State GetOrCreate(LrStateMachine lrStateMachine, ref ParserState p
{
state = new State
{
CurrentState = lrStateMachine.InitialState,
StateStack = new ValueStack<int>(InitialStackCapacity).ExportState(),
SemanticValueStack = new ValueStack<object?>(InitialStackCapacity).ExportState()
StateStack = CreateStack(lrStateMachine.InitialState),
SemanticValueStack = CreateStack<object?>(null)
};
parserState.SetValue(typeof(State), state);
}
return (State)state;

static ValueStack<T>.State CreateStack<T>(T initialValue)
{
var stack = new ValueStack<T>(InitialStackCapacity);
stack.Push(initialValue);
return stack.ExportState();
}
}
}
}

0 comments on commit 112e674

Please sign in to comment.