mirror of
https://github.com/ZuneDev/ZuneUIXTools.git
synced 2026-07-27 13:11:59 -07:00
Remove XML from UIXA parsing
This commit is contained in:
+108
-134
@@ -57,150 +57,124 @@ partial class Lexer
|
|||||||
|
|
||||||
input = Parse.Char('=').Token()(input).Remainder;
|
input = Parse.Char('=').Token()(input).Remainder;
|
||||||
|
|
||||||
// Types that can't be encoded as simple strings, such as FlowLayout,
|
var typeNameResult = QualifiedTypeName.Token()(input);
|
||||||
// are defined inline using XML elements.
|
input = typeNameResult.Remainder;
|
||||||
bool isInlineXml = Parse.Char('<')(input).WasSuccessful;
|
if (!typeNameResult.WasSuccessful)
|
||||||
if (isInlineXml)
|
return Result.Failure<IDirective>(input, "Invalid constant directive", ["Expected qualified name of type to construct"]);
|
||||||
|
|
||||||
|
Markup.MarkupConstantPersistMode? persistMode = null;
|
||||||
|
string content = "";
|
||||||
|
|
||||||
|
var encodingMarkerResult = Parse.Char('.')(input);
|
||||||
|
input = encodingMarkerResult.Remainder;
|
||||||
|
if (!encodingMarkerResult.WasSuccessful)
|
||||||
{
|
{
|
||||||
// Find the end of the XML tag
|
// Support defining constants from string literals
|
||||||
var xmlPartResult = Parse.AnyChar.Until(Parse.String("/>")).Text()(input);
|
var stringLiteralResult = ExpressionInBraces(StringLiteral)(input);
|
||||||
input = xmlPartResult.Remainder;
|
input = stringLiteralResult.Remainder;
|
||||||
if (!xmlPartResult.WasSuccessful)
|
if (!stringLiteralResult.WasSuccessful)
|
||||||
return Result.Failure<IDirective>(input, "Invalid constant directive", ["Expected valid XML"]);
|
return Result.Failure<IDirective>(input, "Invalid constant directive", ["Expected '.', followed by the persist mode."]);
|
||||||
|
|
||||||
var xmlElem = System.Xml.Linq.XElement.Parse($"{xmlPartResult.Value}/>");
|
persistMode = Markup.MarkupConstantPersistMode.FromString;
|
||||||
var xmlPrefix = xmlElem.Name.NamespaceName == string.Empty
|
content = stringLiteralResult.Value[1..^1].Unescape();
|
||||||
? null : xmlElem.Name.NamespaceName;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var persistModeResult = Parse.CharExcept('(').AtLeastOnce().Text().Token()(input);
|
||||||
|
input = persistModeResult.Remainder;
|
||||||
|
if (!persistModeResult.WasSuccessful)
|
||||||
|
return Result.Failure<IDirective>(input, "Invalid constant directive", ["No persist mode was specified."]);
|
||||||
|
|
||||||
QualifiedTypeName typeName = new(xmlPrefix, xmlElem.Name.LocalName);
|
persistMode = persistModeResult.Value.ToLowerInvariant() switch
|
||||||
var content = xmlElem.ToString(System.Xml.Linq.SaveOptions.DisableFormatting);
|
{
|
||||||
|
"bin" => Markup.MarkupConstantPersistMode.Binary,
|
||||||
|
"str" => Markup.MarkupConstantPersistMode.FromString,
|
||||||
|
"can" => Markup.MarkupConstantPersistMode.Canonical,
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
|
|
||||||
directive = new ConstantDirective(constNameResult.Value, typeName, content)
|
var openBracketResult = Parse.Char('(').Token()(input);
|
||||||
|
input = openBracketResult.Remainder;
|
||||||
|
if (!openBracketResult.WasSuccessful)
|
||||||
|
return Result.Failure<IDirective>(input, "Invalid constant directive", ["Expected '('"]);
|
||||||
|
|
||||||
|
var contentResult = Parse.AnyChar.Until(StatementEnd).Text().Token()(input);
|
||||||
|
input = contentResult.Remainder;
|
||||||
|
if (!contentResult.WasSuccessful)
|
||||||
|
return Result.Failure<IDirective>(input, "Invalid constant directive", ["Expected constant value"]);
|
||||||
|
|
||||||
|
content = contentResult.Value;
|
||||||
|
if (content.Length <= 1 || content[^1] != ')')
|
||||||
|
return Result.Failure<IDirective>(input, "Invalid constant directive", ["Expected ')'"]);
|
||||||
|
content = content[..^1];
|
||||||
|
}
|
||||||
|
|
||||||
|
var constantName = constNameResult.Value;
|
||||||
|
var typeName = typeNameResult.Value;
|
||||||
|
|
||||||
|
if (persistMode == Markup.MarkupConstantPersistMode.FromString)
|
||||||
|
{
|
||||||
|
directive = new StringEncodedConstantDirective(constantName, typeName, content)
|
||||||
{
|
{
|
||||||
Line = line,
|
Line = line,
|
||||||
|
Column = column,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (persistMode == Markup.MarkupConstantPersistMode.Canonical)
|
||||||
|
{
|
||||||
|
directive = new CanonicalInstanceConstantDirective(constantName, typeName, content)
|
||||||
|
{
|
||||||
|
Line = line,
|
||||||
|
Column = column,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (persistMode == Markup.MarkupConstantPersistMode.Binary)
|
||||||
|
{
|
||||||
|
byte[] constantBytes;
|
||||||
|
var byteParts = content.Split(',');
|
||||||
|
if (byteParts.Length == 1)
|
||||||
|
{
|
||||||
|
var constantStr = byteParts[0].Trim();
|
||||||
|
if (constantStr.StartsWith("0x"))
|
||||||
|
{
|
||||||
|
constantStr = constantStr[2..];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (constantStr.Length == 2)
|
||||||
|
{
|
||||||
|
constantBytes = [byte.Parse(constantStr, NumberStyles.HexNumber)];
|
||||||
|
}
|
||||||
|
else if (constantStr.Length == 4)
|
||||||
|
{
|
||||||
|
constantBytes = BitConverter.GetBytes(
|
||||||
|
ushort.Parse(constantStr, NumberStyles.HexNumber));
|
||||||
|
}
|
||||||
|
else if (constantStr.Length == 8)
|
||||||
|
{
|
||||||
|
constantBytes = BitConverter.GetBytes(
|
||||||
|
uint.Parse(constantStr, NumberStyles.HexNumber));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Result.Failure<IDirective>(input, "Invalid constant directive", [$"Expected a 1-, 2-, or 4-digit hex number, or a list of bytes"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
constantBytes = byteParts
|
||||||
|
.Select(s => byte.Parse(s.Trim().TrimStart('0', 'x'), NumberStyles.HexNumber))
|
||||||
|
.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
directive = new BinaryEncodedConstantDirective(constantName, typeName, constantBytes)
|
||||||
|
{
|
||||||
|
Line = line,
|
||||||
|
Column = column,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var typeNameResult = QualifiedTypeName.Token()(input);
|
return Result.Failure<IDirective>(input, "Invalid constant directive", [$"Invalid persist mode"]);
|
||||||
input = typeNameResult.Remainder;
|
|
||||||
if (!typeNameResult.WasSuccessful)
|
|
||||||
return Result.Failure<IDirective>(input, "Invalid constant directive", ["Expected qualified name of type to construct"]);
|
|
||||||
|
|
||||||
Markup.MarkupConstantPersistMode? persistMode = null;
|
|
||||||
string content = "";
|
|
||||||
|
|
||||||
var encodingMarkerResult = Parse.Char('.')(input);
|
|
||||||
input = encodingMarkerResult.Remainder;
|
|
||||||
if (!encodingMarkerResult.WasSuccessful)
|
|
||||||
{
|
|
||||||
// Support defining constants from string literals
|
|
||||||
var stringLiteralResult = ExpressionInBraces(StringLiteral)(input);
|
|
||||||
input = stringLiteralResult.Remainder;
|
|
||||||
if (!stringLiteralResult.WasSuccessful)
|
|
||||||
return Result.Failure<IDirective>(input, "Invalid constant directive", ["Expected '.', followed by the persist mode."]);
|
|
||||||
|
|
||||||
persistMode = Markup.MarkupConstantPersistMode.FromString;
|
|
||||||
content = stringLiteralResult.Value[1..^1].Unescape();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var persistModeResult = Parse.CharExcept('(').AtLeastOnce().Text().Token()(input);
|
|
||||||
input = persistModeResult.Remainder;
|
|
||||||
if (!persistModeResult.WasSuccessful)
|
|
||||||
return Result.Failure<IDirective>(input, "Invalid constant directive", ["No persist mode was specified."]);
|
|
||||||
|
|
||||||
persistMode = persistModeResult.Value.ToLowerInvariant() switch
|
|
||||||
{
|
|
||||||
"bin" => Markup.MarkupConstantPersistMode.Binary,
|
|
||||||
"str" => Markup.MarkupConstantPersistMode.FromString,
|
|
||||||
"can" => Markup.MarkupConstantPersistMode.Canonical,
|
|
||||||
_ => null
|
|
||||||
};
|
|
||||||
|
|
||||||
var openBracketResult = Parse.Char('(').Token()(input);
|
|
||||||
input = openBracketResult.Remainder;
|
|
||||||
if (!openBracketResult.WasSuccessful)
|
|
||||||
return Result.Failure<IDirective>(input, "Invalid constant directive", ["Expected '('"]);
|
|
||||||
|
|
||||||
var contentResult = Parse.AnyChar.Until(StatementEnd).Text().Token()(input);
|
|
||||||
input = contentResult.Remainder;
|
|
||||||
if (!contentResult.WasSuccessful)
|
|
||||||
return Result.Failure<IDirective>(input, "Invalid constant directive", ["Expected constant value"]);
|
|
||||||
|
|
||||||
content = contentResult.Value;
|
|
||||||
if (content.Length <= 1 || content[^1] != ')')
|
|
||||||
return Result.Failure<IDirective>(input, "Invalid constant directive", ["Expected ')'"]);
|
|
||||||
content = content[..^1];
|
|
||||||
}
|
|
||||||
|
|
||||||
var constantName = constNameResult.Value;
|
|
||||||
var typeName = typeNameResult.Value;
|
|
||||||
|
|
||||||
if (persistMode == Markup.MarkupConstantPersistMode.FromString)
|
|
||||||
{
|
|
||||||
directive = new StringEncodedConstantDirective(constantName, typeName, content)
|
|
||||||
{
|
|
||||||
Line = line,
|
|
||||||
Column = column,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else if (persistMode == Markup.MarkupConstantPersistMode.Canonical)
|
|
||||||
{
|
|
||||||
directive = new CanonicalInstanceConstantDirective(constantName, typeName, content)
|
|
||||||
{
|
|
||||||
Line = line,
|
|
||||||
Column = column,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else if (persistMode == Markup.MarkupConstantPersistMode.Binary)
|
|
||||||
{
|
|
||||||
byte[] constantBytes;
|
|
||||||
var byteParts = content.Split(',');
|
|
||||||
if (byteParts.Length == 1)
|
|
||||||
{
|
|
||||||
var constantStr = byteParts[0].Trim();
|
|
||||||
if (constantStr.StartsWith("0x"))
|
|
||||||
{
|
|
||||||
constantStr = constantStr[2..];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (constantStr.Length == 2)
|
|
||||||
{
|
|
||||||
constantBytes = [byte.Parse(constantStr, NumberStyles.HexNumber)];
|
|
||||||
}
|
|
||||||
else if (constantStr.Length == 4)
|
|
||||||
{
|
|
||||||
constantBytes = BitConverter.GetBytes(
|
|
||||||
ushort.Parse(constantStr, NumberStyles.HexNumber));
|
|
||||||
}
|
|
||||||
else if (constantStr.Length == 8)
|
|
||||||
{
|
|
||||||
constantBytes = BitConverter.GetBytes(
|
|
||||||
uint.Parse(constantStr, NumberStyles.HexNumber));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Result.Failure<IDirective>(input, "Invalid constant directive", [$"Expected a 1-, 2-, or 4-digit hex number, or a list of bytes"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
constantBytes = byteParts
|
|
||||||
.Select(s => byte.Parse(s.Trim().TrimStart('0', 'x'), NumberStyles.HexNumber))
|
|
||||||
.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
directive = new BinaryEncodedConstantDirective(constantName, typeName, constantBytes)
|
|
||||||
{
|
|
||||||
Line = line,
|
|
||||||
Column = column,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Result.Failure<IDirective>(input, "Invalid constant directive", [$"Invalid persist mode"]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,8 @@
|
|||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|
||||||
|
<PackageReference Include="System.Memory" Version="4.6.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
Reference in New Issue
Block a user