Refactor representation of character category in PDT.

This commit is contained in:
2023-11-29 14:51:14 +08:00
parent 6d0975b0a1
commit 5ef6e2b4a3
3 changed files with 37 additions and 41 deletions

View File

@@ -140,24 +140,24 @@ namespace Cryville.Common.Pdt {
PdtExpToken GetToken() {
ws();
var result = new PdtExpToken {
Type = ct & 0x0fe0
Type = ct & (CharCategory)0x0fe0
};
switch (result.Type) {
case 0x0020: result.Value = GetIdentifier(); break;
case 0x0040: result.Value = GetNumber(); break;
case 0x0100: result.Value = GetString(); break;
case CharCategory.IdentifierBegin: result.Value = GetIdentifier(); break;
case CharCategory.Digit : result.Value = GetNumber(); break;
case CharCategory.StringDelimiter: result.Value = GetString(); break;
default: result.Value = cc.ToString(); Position++; break;
}
return result;
}
private struct PdtExpToken {
public int Type { get; set; }
public CharCategory Type { get; set; }
public string Value { get; set; }
public override string ToString() {
return string.Format("0x{0:x4}: {1}", Type, Value);
}
public static readonly PdtExpToken EmptyOperator = new PdtExpToken {
Type = 0x0080,
Type = CharCategory.Operator,
Value = "$",
};
}
@@ -192,7 +192,7 @@ namespace Cryville.Common.Pdt {
t2 = InterpretExpBlock(ins);
panic:
switch (t2.Type) {
case 0x0080:
case CharCategory.Operator:
if (OP_TYPE[t1.Value[0]] != -1) {
int p1 = OP_PRIORITY[t1.Value[0]];
int p2 = OP_PRIORITY[t2.Value[0]];
@@ -213,11 +213,11 @@ namespace Cryville.Common.Pdt {
}
t1 = t2;
break;
case 0x0400:
case CharCategory.ClosingBracket:
if (enc == -2) throw new FormatException("Expression not enclosed correctly: Too many closing brackets");
if (ins.Count == insc0) pc = 0;
goto exit;
case 0x0800:
case CharCategory.EndOfExpression:
goto exit;
}
}
@@ -240,7 +240,7 @@ namespace Cryville.Common.Pdt {
/// <returns>The expression token following this expression block.</returns>
PdtExpToken InterpretExpBlock(LinkedList<PdtInstruction> ins) {
var t = GetToken();
if (t.Type == 0x0080) {
if (t.Type == CharCategory.Operator) {
var r = InterpretExpBlock(ins);
ins.AddLast(new PdtInstruction.Operate(t.Value, 1));
return r;
@@ -248,7 +248,7 @@ namespace Cryville.Common.Pdt {
bool flag = false;
PdtExpToken? buf = null;
while (true) {
if (buf != null && t.Type != 0x0200) {
if (buf != null && t.Type != CharCategory.OpeningBracket) {
PdtExpression def;
if (defs.TryGetValue(buf.Value.Value, out def)) {
foreach (var i in def.Instructions) ins.AddLast(i);
@@ -262,14 +262,14 @@ namespace Cryville.Common.Pdt {
TryPushAdjMul(ins, ref flag);
}
switch (t.Type) {
case 0x0020:
case CharCategory.IdentifierBegin:
buf = t;
break;
case 0x0040:
case CharCategory.Digit:
float num = float.Parse(t.Value);
ins.AddLast(new PdtInstruction.PushConstant(PdtInternalType.Number, BitConverter.GetBytes(num)));
break;
case 0x0100:
case CharCategory.StringDelimiter:
int strlen = t.Value.Length;
unsafe {
var strbuf = new byte[strlen * sizeof(char) + sizeof(int)];
@@ -280,7 +280,7 @@ namespace Cryville.Common.Pdt {
ins.AddLast(new PdtInstruction.PushConstant(PdtInternalType.String, strbuf));
}
break;
case 0x0200:
case CharCategory.OpeningBracket:
int pc;
InterpretExp(ins, -1, out pc);
if (buf != null) {

View File

@@ -12,23 +12,19 @@ namespace Cryville.Common.Pdt {
/// Interpreter for Property Definition Tree (PDT) file format.
/// </summary>
public partial class PdtInterpreter {
/// <summary>
/// The character category map.
/// </summary>
/// <remarks>
/// <list type="bullet">
/// <item><term><c>0x0001</c></term><description>White Space</description></item>
/// <item><term><c>0x0010</c></term><description>Identifier</description></item>
/// <item><term><c>0x0020</c></term><description>Identifier Begin</description></item>
/// <item><term><c>0x0040</c></term><description>Digit</description></item>
/// <item><term><c>0x0080</c></term><description>Operator</description></item>
/// <item><term><c>0x0100</c></term><description>String</description></item>
/// <item><term><c>0x0200</c></term><description>Opening Bracket</description></item>
/// <item><term><c>0x0400</c></term><description>Closing Bracket</description></item>
/// <item><term><c>0x0800</c></term><description>End of Expression</description></item>
/// <item><term><c>0x1000</c></term><description>End of Key</description></item>
/// </list>
/// </remarks>
[Flags]
protected enum CharCategory {
WhiteSpace = 0x0001,
Identifier = 0x0010,
IdentifierBegin = 0x0020,
Digit = 0x0040,
Operator = 0x0080,
StringDelimiter = 0x0100,
OpeningBracket = 0x0200,
ClosingBracket = 0x0400,
EndOfExpression = 0x0800,
EndOfKey = 0x1000,
}
static readonly int[] cm = new int[] {
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0000, 0x0000, 0x0001, 0x0000, 0x0000,
@@ -78,14 +74,14 @@ namespace Cryville.Common.Pdt {
/// The category of the character.
/// </summary>
/// <exception cref="IndexOutOfRangeException">The end of the source string is reached.</exception>
protected int ct { get { return cm[cc]; } }
protected CharCategory ct { get { return (CharCategory)cm[cc]; } }
/// <summary>
/// Reads a token until a character of type <paramref name="flag" /> is met.
/// </summary>
/// <param name="flag">The type filter.</param>
/// <returns>A token from the current position (inclusive) to the next character of type <paramref name="flag" /> (exclusive).</returns>
/// <exception cref="IndexOutOfRangeException">No character of type <paramref name="flag" /> is met.</exception>
protected string tokenb(int flag) {
protected string tokenb(CharCategory flag) {
int sp = Position;
while ((ct & flag) == 0) Position++;
return Source.Substring(sp, Position - sp);
@@ -96,7 +92,7 @@ namespace Cryville.Common.Pdt {
/// <param name="flag">The type filter.</param>
/// <returns>A token from the current position (inclusive) to the next character that is not of type <paramref name="flag" /> (exclusive).</returns>
/// <exception cref="IndexOutOfRangeException">No character that is not of type <paramref name="flag" /> is met.</exception>
protected string tokenw(int flag) {
protected string tokenw(CharCategory flag) {
int sp = Position;
while ((ct & flag) != 0) Position++;
return Source.Substring(sp, Position - sp);
@@ -106,7 +102,7 @@ namespace Cryville.Common.Pdt {
/// </summary>
/// <exception cref="IndexOutOfRangeException">The end of the source string is reached.</exception>
protected void ws() {
while ((ct & 0x0001) != 0) Position++;
while ((ct & CharCategory.WhiteSpace) != 0) Position++;
}
#pragma warning restore IDE1006
@@ -126,8 +122,8 @@ namespace Cryville.Common.Pdt {
/// <returns>An identifier.</returns>
/// <exception cref="IndexOutOfRangeException">The end of the source string is reached.</exception>
protected string GetIdentifier() {
if ((ct & 0x0020) == 0) return "";
return tokenw(0x0010);
if ((ct & CharCategory.IdentifierBegin) == 0) return "";
return tokenw(CharCategory.Identifier);
}
/// <summary>
/// Reads a number.
@@ -135,7 +131,7 @@ namespace Cryville.Common.Pdt {
/// <returns>A number.</returns>
/// <exception cref="IndexOutOfRangeException">The end of the source string is reached.</exception>
protected string GetNumber() {
return tokenw(0x0040);
return tokenw(CharCategory.Digit);
}
/// <summary>
/// Reads a string.
@@ -295,7 +291,7 @@ namespace Cryville.Common.Pdt {
/// </summary>
/// <returns>The interpreted key.</returns>
protected virtual object InterpretKey(Type type) {
return tokenb(0x1000).Trim();
return tokenb(CharCategory.EndOfKey).Trim();
}
}
/// <summary>

View File

@@ -79,7 +79,7 @@ namespace Cryville.Crtr.Skin {
}
}
object InterpretAnimationSpanKey() {
if ((ct & 0x0040) != 0 || cc == ',') {
if ((ct & CharCategory.Digit) != 0 || cc == ',') {
float start = 0, end = 1;
if (cc != ',') {
start = float.Parse(GetNumber());