没有正则表达式的解析模板?

时间:2012-06-23 15:31:33

标签: parsing templates

嗯,这是我的问题:我有一个使用自定义Javascript实现的应用程序, 但不支持正则表达式。

但是,我希望能够解析模板;最好使用C ++。

模板可能如下所示(ASP样式模板):

<% var foo = someFunction("with a string");
   var bar =  anotherFunction(["with", "an", "array"]); %>

<b>This is html, and this is a variable: <%= bar %></b>

<% if(foo) { %>
    <b> foo is 'true'</b>
<% } else { %>
    <b> foo is 'false'. terrible. </b>
<% } %>

所以一般结构非常简单(我假设,相对可解析)。

我的问题是,是否可以使用while()循环解析这样的模板,遍历每个字符,而不是使用正则表达式?

既然我这样做的尝试失败了,怎么可能呢?

谢谢!

4 个答案:

答案 0 :(得分:3)

这样的模板很容易解析。

关键是要认识到这些模板基本上只包含两种字符串的序列:样板(HTML)文本和脚本文本。

锅炉板文本基本上以“%&gt;”开头并以“&lt;%”结尾(特殊情况在begin-template和end-template)。脚本文本就是其他一切。是的,您可以为每个监视“&lt;%”,“%&gt;”的每个循环选择两个循环或“模板结束”。该序列隐含在来回交替中。这使得解析器非常简单:

  while not eof
       boilerplate="";
       while next_characters~="<%" or eof
          boilerplate concat next_characters
       end
       scripttext="";
       while next_characters~="%>" or eof
          scripttext concat next_characters
       end
  end

(我留下了编码员个人角色管理的细节)。

你没有说的是你想要用解析的结果。如果目标是从解析结果中“生成输出”,则必须将其转换为程序。 这实际上非常简单。

基本上,您将结果写入文件并进行编译。 对于每个收集的样板文本,发出打印样板文本的print语句;你可能必须转义字符,使它们在你选择的目标语言的字符串文字中合法,或者将样板分成多个块来打印它。对于每个脚本文本块,只需发出不变的。您可能必须发出一个prolog文本块来创建一个函数头,并作为postlog文本块来使函数结束。

就是这样。

[由于这些“模板”和带有print语句的简单程序之间的微不足道的转换,我发现这样的模板编程并不是很诱人。它为我节省了一些打印关键字,就是这样。]

答案 1 :(得分:1)

这是我在你的案子中尝试的:

  1. 编写一个返回一组已知标记的标记生成器(带有它们所代表的确切字符串,例如:ID("someFunction")

  2. 使用上述代码编写formal grammar,其中描述了可接受的模板格式

  3. 编写一个识别语法的解析器(例如push-down automatonLR parserLALR parser))

  4. 注意:确保语法符合您正在实施的解析器的限制;如果没有,重写语法或更改解析器

    注意:确保您彻底测试解析器,因为实现中的错误很难调试

    注意:在解析步骤中,如果要获取已解析模板的语义(含义),则需要执行一些附加操作,而不仅仅是它是否是有效模板。这些额外的步骤涉及存储变量/函数的ID(记住附加到标记的字符串?),在引用时查找它们,检查函数参数编号等。

答案 2 :(得分:1)

您是否考虑过使用Finite State Machine?以下是一些供您查看的链接。

简而言之:FSM由有限数量的状态和这些状态之间的转换组成。因此,解析过程可能表示如下(伪代码):

myFSM = new FSM( /* states, transitions */ );
// now your FSM is at initial state.

while not end of file {       
  switch (myFSM->currentState) {   
    case 'IF':
      // Does current line contain closing if? or else? If so, do a transition
      // to state that grabs everything in if construct 
      ...
    case 'TEXT': 
      // Lines do not have any lexical constructs, and we are outside any blocks
      ...
    ...

  }
}

当然,这非常简单。真正的解析器看起来会有所不同。但我希望你有个主意。

答案 3 :(得分:0)

您可能已经有了现有的解决方案。

无逻辑模板库:

https://github.com/leonidas/transparency/wiki/Frequently-Asked-Questions

(见最后一个问题)。