作为宠物项目,我想尝试实现我自己设计的基本语言,可以用作网络脚本语言。将C ++程序作为Apache CGI运行是微不足道的,因此真正的工作在于如何解析包含非代码(HTML / CSS标记)和服务器端代码的输入文件。
在我的本科编译课程中,我们使用Flex和Bison为简单语言生成扫描程序和解析器。我们得到了一份语法副本,并编写了一个解析器,将简单语言翻译成虚拟机的简单程序集。 flex扫描器将输入标记化,并将标记传递给Bison解析器。
与我想做的事情之间的区别在于,与PHP一样,这种语言可以使用纯HTML标记,并且脚本语言散布如下:
<p>Hello,
<? echo "World ?>
</p>
我认为解析输入文件效率如下是错误的:
基本上,第一个扫描程序仅区分Markup(直接返回到未修改的浏览器)和代码,代码传递给第二个扫描程序,后者又将代码标记化并将标记传递给解析器。
如果不是一个可靠的设计模式,PHP等语言如何有效地处理扫描输入和解析代码?
答案 0 :(得分:6)
你想看一下开始条件。例如:
"<?" { BEGIN (PHP); }
<PHP>[a-zA-Z]* { return PHP_TOKEN; }
<PHP>">?" { BEGIN (0); }
[a-zA-Z]* { return HTML_TOKEN; }
从状态0开始,使用BEGIN宏来改变状态。 要仅在特定状态下匹配RE,请在RE前面加上由尖括号括起的状态名称。
在上面的例子中,“PHP”是状态。 “PHP_TOKEN”和“HTML_TOKEN”是yacc文件定义的_%token_s。
答案 1 :(得分:2)
PHP不区分扫描和标记。它只是在标记模式下输出到缓冲区,然后在代码模式下切换到解析。您不需要双通扫描仪,只需一个flex lexer即可完成此操作。
如果您对PHP本身如何工作感兴趣,请下载源代码(尝试PHP4源代码,它更容易理解)。您想要查看的是Zend目录zend_language_scanner.l
。
自己写了类似的东西后,我真的建议重新考虑去Flex和Bison的路线,然后选择像Antlr这样的现代东西。它更容易理解(lex语法中使用的宏变得非常混乱且难以阅读)并且它具有内置调试器(AntlrWorks),因此您不必花费数小时查看3 Meg调试文件。它还支持多种语言(Java,c#,C,Python,Actionscript),并且拥有一本优秀的书籍和一个非常好的网站,应该能够让您立即启动并运行。