嗯,这是我的问题:我有一个使用自定义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()
循环解析这样的模板,遍历每个字符,而不是使用正则表达式?
既然我这样做的尝试失败了,怎么可能呢?
谢谢!
答案 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)
这是我在你的案子中尝试的:
编写一个返回一组已知标记的标记生成器(带有它们所代表的确切字符串,例如:ID("someFunction")
)
使用上述代码编写formal grammar,其中描述了可接受的模板格式
编写一个识别语法的解析器(例如push-down automaton,LR parser或LALR parser))
注意:确保语法符合您正在实施的解析器的限制;如果没有,重写语法或更改解析器
注意:确保您彻底测试解析器,因为实现中的错误很难调试
注意:在解析步骤中,如果要获取已解析模板的语义(含义),则需要执行一些附加操作,而不仅仅是它是否是有效模板。这些额外的步骤涉及存储变量/函数的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
(见最后一个问题)。