-1

我需要在文本中识别 {scope},例如源代码。我从一行开始,将扩展为搜索多行,并排除注释。我已经有使用模式匹配器的工作代码,但我想批评如何改进这种搜索。

String line = "{{outside{inside}{inside2}}};";
String scopeOf = "outside";
findscope(line,scopeOf);


private static void findscope(String line,
                              String scopeOf) {

    int layer = 1;
    Pattern p = Pattern.compile(scopeOf);
    Matcher m = p.matcher(line);
    if (m.find()) {
        int scopestart = m.start();
        int scopeEnd = Integer.MIN_VALUE;
        m.usePattern(Pattern.compile("\\{|\\}"));
        while (m.find()) {
            String group = m.group();
            if (group.equals("{")) {
                layer++;
            } else if (group.equals("}")) {
                layer--;
            }
            if (layer == 0) {
                scopeEnd = m.start();
                break;
            }
        }
        System.out.println("Scope of " + scopeOf + " starts at " + scopestart +
        " finishes at " + scopeEnd);

    }
}
4

1 回答 1

1

好吧,您使用了错误的工具来完成这项工作(假设您也在寻找嵌套范围)

请注意,正则表达式(正则表达式的传统形式)代表正则表达式 - 这是一种描述正则语言的方式。

但是,该语言L = { all words with legal scopings }是不规则的 - 因此无法通过正则表达式识别。

这种语言实际上是Conext Free Langauge,可以用Context Free Grammer来表示。

对于解析:
对于相对简单的语言(范围是其中之一) - 确定性下推自动机足以验证它们。

有些语言需要非确定性下推自动机——创建效率不高,但也有一个动态编程算法来解析它们。


附带说明一下,您可以使用一些工具(例如JavaCC)来解析(并生成代码/输出) - 看看它们,但如果您只是在寻找范围界定问题 - 这可能是一种矫枉过正。


编辑 - 伪代码:

curr <- 0
count <- 0 //integer imitates the stack for this simple usage
l <- string.length()
while (curr < l):
   if string.charAt(curr) == '{':
         count++;
   else if string.charAt(curr) == '}':
         if curr <= 0:
              return ERROR;
         count--;
   curr++;
if count != 0:
    return ERROR;
return SUCCESS;

注意这里我们可以使用一个整数来模拟堆栈,这里的增加基本上是一个push(),而减少是一个pop()。

于 2013-10-19T16:00:37.027 回答