解析Latex文档时的树顶无限循环

时间:2013-01-14 04:29:22

标签: ruby treetop

我正在尝试用treetop编写一个解析器来将一些乳胶命令解析为HTML标记。通过以下内容,我在生成的代码中获得了一个死胡同。我用tt构建源代码并逐步完成,但它并没有真正阐明底层问题是什么(它只是在_nt_paragraph中旋转)

Test input: "\emph{hey} and some more text."

grammar Latex
  rule document
    (paragraph)* {
      def content
        [:document, elements.map { |e| e.content }]
      end
    }
  end

  # Example: There aren't the \emph{droids you're looking for} \n\n. 
  rule paragraph
    ( text / tag )* eop {
      def content
        [:paragraph, elements.map { |e| e.content } ]
      end
    }
  end

  rule text
    ( !( tag_start / eop) . )* {
      def content
        [:text, text_value ]
      end
    }
  end

  # Example: \tag{inner_text}
  rule tag
    "\\emph{" inner_text '}' {
      def content
        [:tag, inner_text.content]
      end
    }
  end 

  # Example: \emph{inner_text}
  rule inner_text
    ( !'}' . )* {
      def content
        [:inner_text, text_value]
      end
    }
  end

  # End of paragraph.
  rule eop
    newline 2.. {
      def content
        [:newline, text_value]
      end
    }
  end

  rule newline
    "\n"
  end

  # You know, what starts a tag
  rule tag_start
    "\\"
  end

end

1 个答案:

答案 0 :(得分:0)

对于任何好奇的人,克利福德在树梢开发谷歌团队认识到了这一点。

问题在于段落和文字。

文本是0个或更多个字符,并且段落中可以有0个或更多文本,所以发生的事情是在第一个\ n之前存在无限量的0个长度字符,导致解析器停止旋转。解决方法是将文本调整为:

( !( tag_start / eop) . )+

因此必须至少有一个字符匹配。