Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/EasyCon.Script/Syntax/Parser.Fn.cs
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ private ExprBase ParseExpression(int parentPrecedence = 0)
{
ExprBase left;
var unaryOperatorPrecedence = Current.Type.GetUnaryOperatorPrecedence();
if (unaryOperatorPrecedence != 0 && unaryOperatorPrecedence >= parentPrecedence)
if (unaryOperatorPrecedence != 0 && unaryOperatorPrecedence >= parentPrecedence && !CursorEOF)
{
var opToken = Advance();
var operand = ParseExpression(unaryOperatorPrecedence);
Expand Down
2 changes: 1 addition & 1 deletion src/EasyCon2/App/MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using EasyCon2.Avalonia.Core.VPad;
using EasyCon2.Forms;
using EasyCon2.Helper;
using Resources = EasyCon2.UI.Common.Properties.Resources;
using EasyCon2.Views;
using EasyDevice;
using EasyScript;
Expand All @@ -24,6 +23,7 @@
using System.Xml;
using AvaColor = Avalonia.Media.Color;
using AvaColors = Avalonia.Media.Colors;
using Resources = EasyCon2.UI.Common.Properties.Resources;

namespace EasyCon2.App;

Expand Down
2 changes: 1 addition & 1 deletion src/EasyCon2/EasyConForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using EasyCon.Script.Assembly;
using EasyCon2.Avalonia.Core.VPad;
using EasyCon2.Helper;
using Resources = EasyCon2.UI.Common.Properties.Resources;
using EasyCon2.Views;
using EasyDevice;
using EasyScript;
Expand All @@ -21,6 +20,7 @@
using System.Xml;
using AvaColor = Avalonia.Media.Color;
using AvaColors = Avalonia.Media.Colors;
using Resources = EasyCon2.UI.Common.Properties.Resources;

namespace EasyCon2.Forms
{
Expand Down
2 changes: 1 addition & 1 deletion src/EasyCon2/Forms/CaptureVideoForm.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
using EasyCon.Capture;
using EasyCon2.Helper;
using Resources = EasyCon2.UI.Common.Properties.Resources;
using OpenCvSharp.Extensions;
using System.Diagnostics;
using System.Drawing.Drawing2D;
using System.IO;
using Mat = OpenCvSharp.Mat;
using Resources = EasyCon2.UI.Common.Properties.Resources;

namespace EasyCon2.Forms
{
Expand Down
2 changes: 1 addition & 1 deletion src/EasyCon2/Forms/ESPConfig.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using EasyCapture;
using EasyCon2.Models;
using Resources = EasyCon2.UI.Common.Properties.Resources;
using EasyDevice;
using LibAmiibo.Data;
using LibAmiibo.Data.Figurine;
Expand All @@ -10,6 +9,7 @@
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using Resources = EasyCon2.UI.Common.Properties.Resources;

namespace EasyCon2.Forms
{
Expand Down
4 changes: 2 additions & 2 deletions src/EasyCon2/ResourceHelper.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
using System.IO;
using EasyCon2.UI.Common.Properties;
using System.IO;

namespace EasyCon2;

internal static class ResourceHelper
{
public static Bitmap Clrlog => new(new MemoryStream(Resources.clrlog));
public static Icon CaptureVideoIcon => new(new MemoryStream(Resources.CaptureVideo));
}
}
206 changes: 206 additions & 0 deletions test/EasyCon.Tests/ParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,212 @@ public void Error_InvalidEOF()

#endregion

#region 表达式解析健壮性测试

// === 正常表达式 ===

[Test]
public void Expr_SimpleBinary()
{
ExpectSuccess("$v = 1 + 2");
ExpectSuccess("$v = 3 - 4");
ExpectSuccess("$v = 5 * 6");
ExpectSuccess("$v = 8 / 2");
ExpectSuccess("$v = 10 % 3");
ExpectSuccess("$v = 1 \\ 2");
}

[Test]
public void Expr_BinaryWithVariables()
{
ExpectSuccess("$v = $a + $b");
ExpectSuccess("$v = $a * $b - $c");
ExpectSuccess("$v = $a + $b * $c"); // 优先级: * > +
}

[Test]
public void Expr_ComparisonOperators()
{
ExpectSuccess("$v = 1 == 2");
ExpectSuccess("$v = 1 != 2");
ExpectSuccess("$v = 3 > 2");
ExpectSuccess("$v = 1 < 2");
ExpectSuccess("$v = 3 >= 2");
ExpectSuccess("$v = 1 <= 2");
}

[Test]
public void Expr_LogicalOperators()
{
ExpectSuccess("$v = 1 and 0");
ExpectSuccess("$v = 1 or 0");
ExpectSuccess("$v = not 0");
}

[Test]
public void Expr_BitwiseOperators()
{
ExpectSuccess("$v = 5 & 3");
ExpectSuccess("$v = 5 | 3");
ExpectSuccess("$v = 5 ^ 3");
ExpectSuccess("$v = ~5");
ExpectSuccess("$v = 1 << 2");
ExpectSuccess("$v = 4 >> 1");
}

[Test]
public void Expr_UnaryMinus()
{
ExpectSuccess("$v = -1");
ExpectSuccess("$v = -$a");
ExpectSuccess("$v = -($a + $b)");
}

[Test]
public void Expr_Parenthesized()
{
ExpectSuccess("$v = (1 + 2)");
ExpectSuccess("$v = (1 + 2) * 3");
ExpectSuccess("$v = ((1 + 2) * (3 - 4))");
}

[Test]
public void Expr_NestedBinary()
{
ExpectSuccess("$v = 1 + 2 + 3");
ExpectSuccess("$v = 1 + 2 * 3 - 4 / 2");
ExpectSuccess("$v = 1 == 2 and 3 > 0");
}

[Test]
public void Expr_ComplexPrecedence()
{
// 完整优先级链: or < and < 比较 < +/-/|/^ < */\%&<</>> < 一元
ExpectSuccess("$v = 1 + 2 * 3 and 4 == 5");
ExpectSuccess("$v = (1 + 2) * (3 - 4) or $a > $b");
}

[Test]
public void Expr_WithConstant()
{
ExpectSuccess("_PI = 3\n$v = _PI + 1");
ExpectSuccess("$v = _PI * 2");
}

[Test]
public void Expr_WithFunctionCall()
{
ExpectSuccess("$v = RAND(10)");
ExpectSuccess("$v = RAND($max) + 1");
ExpectSuccess("$v = TIME()");
}

// === 错误表达式(不完整 binary expression)===

[Test]
public void Expr_Error_TrailingOperator()
{
// 操作符后没有右操作数
ExpectError("$v = 1 +");
ExpectError("$v = 1 -");
ExpectError("$v = 1 *");
ExpectError("$v = 1 /");
ExpectError("$v = 1 %");
}

[Test]
public void Expr_Error_MultipleTrailingOperators()
{
// 连续操作符
ExpectError("$v = 1 + *");
ExpectError("$v = 1 + -");
ExpectError("$v = 1 * /");
}

[Test]
public void Expr_Error_OnlyOperator()
{
// 只有一个操作符
ExpectError("+$v");
ExpectError("-"); // 只有一个减号
}

[Test]
public void Expr_Error_TrailingComparison()
{
ExpectError("$v = 1 ==");
ExpectError("$v = 1 !=");
ExpectError("$v = 1 >");
ExpectError("$v = 1 <");
}

[Test]
public void Expr_Error_TrailingLogical()
{
ExpectError("$v = 1 and");
ExpectError("$v = 1 or");
}

[Test]
public void Expr_Error_TrailingBitwise()
{
ExpectError("$v = 1 &");
ExpectError("$v = 1 |");
ExpectError("$v = 1 ^");
ExpectError("$v = 1 <<");
ExpectError("$v = 1 >>");
}

[Test]
public void Expr_Error_UnmatchedParen()
{
ExpectError("$v = (1 + 2");
// 右括号不匹配在 parser 里可能和左括号路径不同
}

[Test]
public void Expr_Error_EmptyParens()
{
// 空括号不应该是合法表达式(除非是函数调用)
// 具体行为取决于 ParsePrimary 对 LeftParen 的处理
}

[Test]
public void Expr_Error_BinaryInIfCondition()
{
// IF 中的表达式也需要健壮
ExpectError("IF $a +\nA\nENDIF");
ExpectError("IF $a ==\nA\nENDIF");
ExpectError("IF $a >\nA\nENDIF");
}

[Test]
public void Expr_Error_BinaryInForRange()
{
// FOR 中的表达式
ExpectError("FOR $a = 1 +\nNEXT");
}

[Test]
public void Expr_Error_ComplexTrailing()
{
// 更复杂的未完成表达式
ExpectError("$v = (1 + 2) *");
ExpectError("$v = 1 + 2 *");
ExpectError("$v = $a + $b *");
}

[Test]
public void Expr_Error_AugmentedAssignmentTrailing()
{
// 复合赋值后没有右操作数
ExpectError("$v += ");
ExpectError("$v -= ");
ExpectError("$v *= ");
}

#endregion

#region 综合场景测试

[Test]
Expand Down