rj-action-library/Runtime/Godot/Scenes/Parsers/SceneFileMemberParser.cs

127 lines
3.2 KiB
C#

using Godot;
using System.Collections.Generic;
namespace Rokojori
{
public class SceneFileMemberParser
{
public bool hasError = true;
public string errorMessage;
string line;
public void Parse( SceneFileEntry entry )
{
line = entry.line;
var lexer = new SceneFileLexer();
var tokens = lexer.LexToList( line );
if ( lexer.hasError || tokens.Count == 0)
{
errorMessage = "Lexing failed";
return;
}
tokens.RemoveAll( t => t.isDone );
lexer.GrabMatches( tokens, line );
if ( ! tokens[ 0 ].Is( LexerMatcherLibrary.CwordMatcher ) )
{
hasError = true;
errorMessage = RJLog.Stringify( "Expected name as first token, got:", tokens[ 0 ].type, ">>",tokens[ 0 ].match );
return;
}
var assignmentOpResult = LexerEvent.Find( tokens, 1,
t =>
{
if ( t.Is( LexerMatcherLibrary.OperatorMatcher, "=" ) )
{
return LexerEvent.FindResultType.Found;
}
if ( t.Is( LexerMatcherLibrary.WhiteSpaceMatcher ) )
{
return LexerEvent.FindResultType.KeepSearching;
}
return LexerEvent.FindResultType.Error;
}
);
if ( LexerEvent.FindResultType.Found != assignmentOpResult.type )
{
hasError = true;
errorMessage = RJLog.Stringify( "Expected assignment operator:", tokens ) ;
return;
}
var namedValue = new SceneFileNamedValue();
entry.member = namedValue;
namedValue.name = tokens[ 0 ].match;
var valueIndexResult = LexerEvent.Find( tokens, assignmentOpResult.index + 1,
( t )=>
{
if ( t.Is( LexerMatcherLibrary.WhiteSpaceMatcher ) )
{
return LexerEvent.FindResultType.KeepSearching;
}
return LexerEvent.FindResultType.Found;
}
);
if ( LexerEvent.FindResultType.Found != valueIndexResult.type )
{
hasError = true;
errorMessage = RJLog.Stringify( "Expected value after assignment at ", assignmentOpResult.index, "in", tokens ) ;
return;
}
namedValue.value = LexerEvent.GetMatchFromRange( tokens, valueIndexResult.index );
var isList = tokens[ valueIndexResult.index ].Is( LexerMatcherLibrary.BracketMatcher, "[" );
if ( ! isList )
{
namedValue.valueData = new SceneFileValue();
namedValue.valueData.ParseValue( tokens, valueIndexResult.index, tokens.Count - valueIndexResult.index );
return;
}
if ( isList ){ return; }
var separators = LexerEvent.GetSeparatorsInBrackets( tokens, valueIndexResult.index );
var lastIndex = valueIndexResult.index + 1;
namedValue.valuesData = new List<SceneFileValue>();
for ( int i = 0; i < separators.Count; i++ )
{
var v = new SceneFileValue();
v.ParseValue( tokens, lastIndex, separators[ i ] - lastIndex );
namedValue.valuesData.Add( v );
lastIndex = separators[ i ] + 1;
}
var lastV = new SceneFileValue();
lastV.ParseValue( tokens, lastIndex, ( tokens.Count - 1 ) - lastIndex );
}
}
}