Algorithm 用C语言解析脚本循环#
我正在编写一个应用程序,它将用自定义语言(稍微基于C语法和格式)解析脚本,并且正在寻找一种更好(读:更快)的方法,将脚本代码块解析为字符串数组,而不是像我现在这样做(目前的方法可以,但它更适合调试) 脚本内容当前从文件读入字符串数组并传递给方法 下面是一个脚本块模板:Algorithm 用C语言解析脚本循环#,algorithm,c#-3.0,text-parsing,Algorithm,C# 3.0,Text Parsing,我正在编写一个应用程序,它将用自定义语言(稍微基于C语法和格式)解析脚本,并且正在寻找一种更好(读:更快)的方法,将脚本代码块解析为字符串数组,而不是像我现在这样做(目前的方法可以,但它更适合调试) 脚本内容当前从文件读入字符串数组并传递给方法 下面是一个脚本块模板: loop [/* some conditional */ ] { /* a whole bunch of commands that are to be read into * a List<string>,
loop [/* some conditional */ ]
{
/* a whole bunch of commands that are to be read into
* a List<string>, then converted to a string[] and
* passed to the next step for execution */
/* some command that has a bracket delimited set of
* properties or attributes */
{
/* some more commands to be acted on */
}
}
循环[/*某些条件*/]
{
/*一大堆要读入的命令
*列表,然后转换为字符串[]和
*传递到下一步执行*/
/*具有以括号分隔的一组
*属性或属性*/
{
/*还有一些命令需要执行*/
}
}
基本上,花括号块可以嵌套(就像在任何其他基于C的语言中一样),我正在寻找找到这样的单个块的最佳方法
花括号分隔的块将始终设置为这样的格式-括号中的内容将从左括号后的行开始,然后在最后一个属性/命令/注释/任何内容后的行上加上括号
例如:
loop [ someVar <= 10 ]
{
informUser "Get ready to do something"
readValue
{
valueToLookFor = 0x54
timeout = 10 /* in seconds */
}
}
loop[someVar 0)
{
//抛出新异常,这是我们不应该期望的
//找到一行以[当我们已经
}
其他的
{
if(scriptContents[i]。包含('{'))openBraceCount++;
if(scriptContents[i].Contains('}'))closeBraceCount++;
如果(scriptContents[i]。包含('['))openSquareCount++;
如果(scriptContents[i].包含(']')closeBraceCount++;
newIndex=i;
fullblock.Add(脚本内容[i]);
打破
}
}
其他的
{
if(scriptContents[i]。包含(“[”&&fullblock.Count>0)
{
//抛出新异常,这是我们不应该期望的
//找到一行以[当我们已经
}
其他的
{
if(scriptContents[i]。包含('{'))openBraceCount++;
if(scriptContents[i].Contains('}'))closeBraceCount++;
如果(scriptContents[i]。包含('['))openSquareCount++;
如果(scriptContents[i].包含(']')closeBraceCount++;
fullblock.Add(脚本内容[i]);
}
}
}
如果(openBraceCount==closeBraceCount&&
openSquareCount==closeSquareCount)
返回fullblock.ToArray();
其他的
//抛出新异常,开放括号的数量不匹配
//紧括号的数目
}
我同意这可能是一个稍微迟钝和缓慢的方法,这就是为什么我想知道如何重新实现这一点,以达到速度和清晰度(如果可以达到平衡的话)
我希望远离正则表达式,因为我不能用它来保持括号计数,我也不确定是否可以编写一个可以递归操作的正则表达式语句(这是正确的术语吗?)。我想从内到外工作,但我相信这会很慢
我不是想找人帮我重写,而是想找一个关于算法或技术/库的总体想法,我可以用它来改进我的方法
作为一个附带问题,编译器如何处理源代码中的多个嵌套方括号?,由Jack Crenshaw编写,是一篇关于构建基本编译器的精彩易读的介绍。所讨论的技术应该有助于您在这里尝试做什么。由Jack Crenshaw编写,是一篇关于构建basi的精彩易读的介绍c编译器。所讨论的技术应该有助于您在这里尝试执行的操作。看看语法、词法分析器和解析器。它们是解析此代码所需的工具。在快速浏览之后,我将看看它们。让我们构建一个编译器,正如他的回答中所建议的那样。看看语法、词法分析器和解析器。它们是e工具你需要解析它。在我快速浏览了一下之后,我会看看这些。让我们构建一个编译器,正如他的回答中所建议的那样。我会重点检查这个,并尝试从中获取技术。但是我担心我会花工作时间阅读大量的系列文章。不过,我还是会这么做。谢谢你的链接,我会的注意检查一下,并尝试从中吸取技巧。但我担心会花工作时间阅读大量系列文章。不过我还是会这样做。谢谢链接
private string[] findEntireBlock(string[] scriptContents, int indexToReadFrom,
out int newIndex)
{
newIndex = 0;
int openBraceCount = 0; // for '{' char count
int closeBraceCount = 0; // for '}' char count
int openSquareCount = 0; // for '[' char count
int closeSquareCount = 0; // for ']' char count
List<string> fullblock = new List<string>();
for (int i = indexToReadFrom; i < scriptContents.Length; i++)
{
if (scriptContents[i].Contains('}'))
{
if (scriptContents[i].Contains("[") && fullblock.Count > 0)
{
//throw new exception, as we shouldn't expect to
//to find a line which starts with [ when we've already
}
else
{
if (scriptContents[i].Contains('{')) openBraceCount++;
if (scriptContents[i].Contains('}')) closeBraceCount++;
if (scriptContents[i].Contains('[')) openSquareCount++;
if (scriptContents[i].Contains(']')) closeBraceCount++;
newIndex = i;
fullblock.Add(scriptContents[i]);
break;
}
}
else
{
if (scriptContents[i].Contains("[") && fullblock.Count > 0)
{
//throw new exception, as we shouldn't expect to
//to find a line which starts with [ when we've already
}
else
{
if (scriptContents[i].Contains('{')) openBraceCount++;
if (scriptContents[i].Contains('}')) closeBraceCount++;
if (scriptContents[i].Contains('[')) openSquareCount++;
if (scriptContents[i].Contains(']')) closeBraceCount++;
fullblock.Add(scriptContents[i]);
}
}
}
if (openBraceCount == closeBraceCount &&
openSquareCount == closeSquareCount)
return fullblock.ToArray();
else
//throw new exception, the number of open brackets doesn't match
//the number of close brackets
}