所以是的,我正在制作Brainfuck解释器,但我还需要从代码中创建AST。 原始操作(+ - 。,><)可以非常容易地在节点中使用。另一方面,循环操作看起来非常复杂。所以,我需要的是在[和]节点之间建立链接。为此我在节点中使用了一个特殊的Node字段。
现在我认为我可以通过在字符串中使用括号位置来创建它们之间的链接。但这是一个问题 - 如何创建匹配的括号对?
以下是我的代码示例:
private readonly List<int> rightBracketsIds;
private readonly List<int> leftBracketsIds;
private List<Tuple<int, int>> lsTuples;
我通过使用特殊方法得到括号位置并将它们放在相应的列表中。但是我应该用什么来创建它们呢? 像
++[>+[>++<-]<-]++[>++<-]>.
LBs:2,5,17
RB:11,14,23
所以我需要得到Tuples&lt; 2,14&gt; &lt; 5,11&gt; &lt; 17,23&gt;。
好吧,我可以看到右支架的位置必须大于左支架的位置:通过查看LB 17和RB 14,我们可以说它们没有连接在一起。但我认为有一种方法可以让它变得更好。
所以是的,任何答案都会有所帮助。抱歉我的英语不好。
P.S。我已经考虑了Stack,但我不知道如何在我的问题中使用它。 P.P.S.我终于发现了一些有用的东西:How to find the matching pair of braces in a string?
如果我能解决我的问题,我会在这里发布解决方案。
答案 0 :(得分:1)
这是一个&#34;不是非常有效但直截了当的&#34;方式。
对于每个左括号X
,请执行以下操作来查找其对:
bracketCount
X
bracketCount
bracketCount
是否为0,如果是,则您找到与X
对应的结束括号!如果不是0,则从bracketCount
减去1。答案 1 :(得分:0)
据我所知,如果您创建Tuple
,则需要两个值。因此,我会推出自己的课程:
class MyTuple { public int A; public int B; }
然后,在解析期间,每次遇到左括号时,请创建MyTuple
并将位置指定给.A
。然后,您Push
上的Stack
此实例。继续解析,如果您遇到另一个左括号,则创建一个新的MyTuple
实例,并将Psuh
也添加到您的Stack
变量中。如果您从Pop
遇到一个结束括号Stack
的一个实例,请指定.B
值并将其作为已完成的对添加到您的数据结构中。
var s = "brainfuck";
var q = new Stack<MyTuple>();
var res = new YourResultClass();
for(int i = 0; i < s.Length; i++)
{
if(s[i] == '[')
{
var m = new MyTuple();
m.A = i;
q.Push(m);
}
if(s[i] == ']')
{
var e = q.Pop();
e.B = i;
res.lsTuples.Add(e);
}
}
if(q.Count > 0)
throw new IOException();
答案 2 :(得分:0)
嗯,我有各种输入异常,所以我只能使用一个堆栈。
class Program
{
static void Main(string[] args)
{
Solver s = new Solver();
s.Solve("++[>+[>++<-]<-]++[>++<-]>.");
s.Visualize();
Console.Read();
}
}
public class Solver
{
private readonly List<int> rightBracketsIds;
private readonly List<int> leftBracketsIds;
private readonly List<Tuple<int, int>> lsTuples;
public Solver()
{
rightBracketsIds = new List<int>();
leftBracketsIds = new List<int>();
lsTuples = new List<Tuple<int, int>>();
}
public void Solve(string s)
{
Stack<int> st = new Stack<int>();
for (int i = 0; i < s.Length; i++)
{
switch (s[i])
{
case '[':
st.Push(i);
break;
case ']':
int index = st.Any() ? st.Pop() : -1;
lsTuples.Add(new Tuple<int, int>(index, i));
break;
}
}
}
public void Visualize()
{
foreach (Tuple<int, int> tuple in lsTuples)
{
Console.WriteLine(tuple.Item1 + " " + tuple.Item2);
}
}
}
对我来说似乎足够好。