regex interpreter now can build partial correct AST (i forget groups), but in bad shape. building an optimizer.
This commit is contained in:
@@ -53,13 +53,18 @@ namespace StgSharp.RegularAnalysis.TextRegex
|
||||
{
|
||||
if ((token.Flag & RegexElementLabel.SEQUENCE) != 0)
|
||||
{
|
||||
Console.WriteLine($"Unit {token.Value}");
|
||||
|
||||
// char or charset
|
||||
_stack.PushOperand(new RegexAstNode(token));
|
||||
} else if ((token.Flag & RegexElementLabel.GROUP_BEGIN) != 0)
|
||||
{
|
||||
Console.WriteLine($"Group begin {token.Value}");
|
||||
_stack.IncreaseDepth(0);
|
||||
} else if ((token.Flag & RegexElementLabel.GROUP_END) != 0)
|
||||
{
|
||||
Console.WriteLine($"Group end {token.Value}");
|
||||
|
||||
// TODO: close all nodes here
|
||||
while (_stack.TryPopOperator(out RegexAstNode? op))
|
||||
{
|
||||
@@ -69,14 +74,61 @@ namespace StgSharp.RegularAnalysis.TextRegex
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
_stack.DecreaseDepth();
|
||||
} else if ((token.Flag & RegexElementLabel.OPERATOR) != 0) { }
|
||||
} else if ((token.Flag & RegexElementLabel.OPERATOR) != 0)
|
||||
{
|
||||
Console.WriteLine($"Operator {token.Value} with flag {token.Flag}");
|
||||
if (_stack.OperatorInDepthCount == 0)
|
||||
{
|
||||
// the first operator in stack
|
||||
_stack.PushOperator(new RegexAstNode(token));
|
||||
} else
|
||||
{
|
||||
// process operator by precedence
|
||||
while (_stack.TryPeekOperator(out RegexAstNode topOp))
|
||||
{
|
||||
(bool Valid, int Value) cmp = RegexAstNode.ComparePrecedence(token.Flag, topOp.Source.Flag);
|
||||
|
||||
if (!cmp.Valid) {
|
||||
throw new InvalidOperationException("Operators with same precedence are not supported.");
|
||||
}
|
||||
if (cmp.Value < 0)
|
||||
{
|
||||
_stack.PopOperator();
|
||||
ProcessOperator(topOp);
|
||||
continue;
|
||||
} else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
_stack.PushOperator(new RegexAstNode(token));
|
||||
}
|
||||
}
|
||||
}
|
||||
Console.WriteLine(1);
|
||||
if (_stack.Depth == 1)
|
||||
{
|
||||
if (_stack.OperandInDepthCount != 1 || _stack.OperatorInDepthCount != 0)
|
||||
{
|
||||
while (_stack.TryPopOperator(out RegexAstNode? op)) {
|
||||
ProcessOperator(op);
|
||||
}
|
||||
}
|
||||
if (_stack.OperandInDepthCount == 1 && _stack.OperatorInDepthCount == 0)
|
||||
{
|
||||
_tree.Root = _stack.PopOperand();
|
||||
return _tree;
|
||||
}
|
||||
throw new InvalidOperationException("Invalid regular expression syntax.");
|
||||
}
|
||||
throw new InvalidOperationException("Invalid regular expression syntax.");
|
||||
}
|
||||
|
||||
private void ProcessOperator(
|
||||
RegexAstNode op
|
||||
)
|
||||
{
|
||||
Console.WriteLine($"Processing a {op.Source.Flag} operator");
|
||||
if (op.EqualityTypeConvert == RegexElementLabel.CONCAT)
|
||||
{
|
||||
if (_stack.TryPopOperand(out RegexAstNode? _1) &&
|
||||
@@ -85,11 +137,15 @@ namespace StgSharp.RegularAnalysis.TextRegex
|
||||
if (RegexAstNode.TryMergeUnit(_2, _1, out RegexAstNode? _3))
|
||||
{
|
||||
_stack.PushOperand(_3);
|
||||
_tree.AddNode(_3);
|
||||
} else
|
||||
{
|
||||
op.Left = _2;
|
||||
op.Right = _1;
|
||||
_stack.PushOperand(op);
|
||||
_tree.AddNode(op);
|
||||
_tree.AddNode(_1);
|
||||
_tree.AddNode(_2);
|
||||
}
|
||||
} else
|
||||
{
|
||||
@@ -101,6 +157,8 @@ namespace StgSharp.RegularAnalysis.TextRegex
|
||||
{
|
||||
op.Left = _1;
|
||||
_stack.PushOperand(op);
|
||||
_tree.AddNode(_1);
|
||||
_tree.AddNode(op);
|
||||
} else
|
||||
{
|
||||
throw new InvalidOperationException("Insufficient operands for CONCAT operator.");
|
||||
@@ -113,6 +171,9 @@ namespace StgSharp.RegularAnalysis.TextRegex
|
||||
op.Left = _1;
|
||||
op.Right = _2;
|
||||
_stack.PushOperand(op);
|
||||
_tree.AddNode(op);
|
||||
_tree.AddNode(_1);
|
||||
_tree.AddNode(_2);
|
||||
} else
|
||||
{
|
||||
throw new InvalidOperationException("Insufficient operands for CONCAT operator.");
|
||||
|
||||
Reference in New Issue
Block a user