2010-03-18 79 views
4

我需要验证C#方法的内容。C#方法内容验证

我不关心不影响方法范围的语法错误。

我关心字符,将无效解析其余的代码。例如:

method() 
{ 
    /* valid comment */ 
    /*   <-- bad 
    for (i..) { 
    } 
    for (i..) { <-- bad 
} 

我需要验证/修复任何非配对字符。

这包括/ * * /,{}和其他人。

我应该怎么办?

我的第一个想法是正则表达式,但显然不会完成工作。

回答

3

你会更仔细地需要范围的问题,为了得到一个合理的答案。

例如,您打算如何处理包含预处理器指令的方法?

void M() 
{ 

#if FOO 
    for(foo;bar;blah) { 
#else 
    while(abc) { 
#endif 
     Blah(); 
    } 
} 

这是愚蠢但合法,所以你必须处理它。你会把它算作不匹配的大括号吗?

您能提供详细规格正是您想要确定的内容吗?正如我们在本网站上多次看到的那样,人们无法成功构建一个在没有规范的情况下划分两个数字的例程。你所谈论的分析比分两个数字要复杂得多;那些在实际编译器中描述的代码就是成千上万行的代码。

+0

我不需要绝对的解决方案。我试图提供的是一个简单的指标,可能在代码中有错误。 1.如果代码包含preproccesor语句,则不执行任何操作。对于我的用户来说,这是一个极端情况,而且难度更大。 2.如果代码包含一个不匹配的{或/ *,将其突出显示 这并不是很详细,但它确切地说明了我需要的内容。 – jaws 2010-03-19 13:37:23

+0

@ user258651:好的,字符串呢?假设你的代码有一个不匹配的大括号,但包含* Console.WriteLine(“}}}}}”); * - 做这些计数作为大括号结束或不? – 2010-03-19 15:36:12

+0

@ user258651:如果评论包含一个大括号怎么办?你是否把它当作最后的大括号? – 2010-03-19 15:36:39

1

正则表达式当然不是这个问题的答案。正则表达式是用于某些类型的数据验证的有用工具。但是一旦你进入更复杂的数据如匹配大括号或​​注释块的业务,正则表达式不再能完成工作。

这是一篇关于使用正则表达式验证输入时遇到的限制的博客文章。

为了做到这一点,你将不得不写这的确验证了各种各样的解析器。

0

如果您试图“验证”定义方法的字符串的内容,那么您可能会更好,只是尝试使用CodeDom类并将该方法即时编译到内存组合中。

编写您自己的全功能解析器来进行验证将非常非常困难,特别是如果您想支持C#3或更高版本。 Lambda表达式和其他类似的构造将很难“干净地”验证。

0

您在“将解析剩余代码无效的字符”和“语法错误”之间进行错误的二分法。缺少一个大括号(你提到的其中一个问题)是一个语法错误。看起来你的意思是你正在寻找可能破坏范围边界的语法错误?不幸的是,没有可靠的方法来做到这一点,使用完整的解析器。

举个例子:

method() 
{ <-- is missing closing brace 
    /* valid comment */ 
    /*   <-- bad 
    for (i..) { 
    } 
    for (i..) { 
} <-- will be interpreted as the closing brace for the for loop 

有来推断它的for循环唯一缺少的右括号,而不是方法没有通用的,实用的方法。

如果您真的有兴趣寻找这些东西,您应该考虑以编程方式运行编译器并解析结果 - 这是使用最低入口阈值的最佳方法。

+0

该方法的大括号不是我正在验证的一部分。只有内容位于我需要验证的字符串中 – jaws 2010-03-18 21:37:59

+0

我以前曾考虑过这个特定问题,并且看不到为什么缩进无法用于确定最后一个大括号是否适用于该方法。 – 2010-03-18 21:39:19

+0

@ user258651道歉 - 我必须误解你的代码示例,然后。第二个for循环的“< - bad”是什么意思? – Dathan 2010-03-18 22:00:47

1

对于这样的任务,正则表达式不是一件很方便的事情。这通常通过使用如下算法的堆栈来实现:

  1. 创建一个空堆栈S.
  2. while(there left characters){
  3. 阅读字符ch。
  4. 如果是CH的开口括号(任何种类的),将其推到小号
  5. 否则
  6. 如果CH是一个闭合括号(任何种类的),看S.
  7. 顶部
  8. 若S这一点是空的,报告失败。
  9. 如果S的顶部是与c相对应的开头paren,则弹出S并继续到1,这个paren匹配OK。
  10. 其他报告失败。
  11. 如果在输入结束时堆栈S不为空,则返回失败。 其他回报成功。

的更多信息,请http://www.ccs.neu.edu/home/sbratus/com1101/lab4.htmlhttp://codeidol.com/csharp/csharpckbk2/Data-Structures-and-Algorithms/Determining-Where-Characters-or-Strings-Do-Not-Balance/

+0

步骤#4不正确,因为您必须考虑评论。下面的代码会注册为有效,但实际上是无效的:尽管如此,foo(//) – JaredPar 2010-03-18 21:40:05

+0

正则表达式有助于忽略注释或字符串中的内容,您可以一次性匹配整个事件,无需解析器状态。 – 2010-03-18 21:41:43

+0

@JaredPar:行注释只是一个“/”开头匹配“\ n”结束。阻止评论或字符串没有什么不同。 – 2010-03-18 21:42:43