作为宠物项目,我想尝试实现我自己设计的基本语言,可以用作网络脚本语言.将C++程序作为Apache CGI运行是微不足道的,因此真正的工作在于如何解析包含非代码(HTML/CSS标记)和服务器端代码的输入文件.
在我的本科编译课程中,我们使用Flex和Bison为简单语言生成扫描程序和解析器.我们得到了一份语法副本,并编写了一个解析器,将简单语言翻译成虚拟机的简单程序集.flex扫描器将输入标记化,并将标记传递给Bison解析器.
我和我想做的事情之间的区别在于,像PHP一样,这种语言可以有纯HTML标记,脚本语言散布如下:
Hello, echo "World ?>
假设解析输入文件效率如下,我是不正确的:
扫描输入,直到找到脚本开始标记('
第二个扫描程序标记输入文件的服务器端脚本部分(来自打开标记:'')并将标记传递给解析器,解析器无需知道文件中的标记.
控制返回到第一个继续此常规模式的扫描仪.
基本上,第一个扫描程序仅区分Markup(直接返回到未修改的浏览器)和代码,后者传递给第二个扫描程序,后者又将代码标记化并将标记传递给解析器.
如果这不是一个可靠的设计模式,PHP等语言如何有效地处理扫描输入和解析代码?
你想看看开始条件.例如:
"" { BEGIN (PHP); }[a-zA-Z]* { return PHP_TOKEN; } ">?" { BEGIN (0); } [a-zA-Z]* { return HTML_TOKEN; }
从状态0开始,使用BEGIN宏来改变状态.要仅在特定状态下匹配RE,请在RE前面加上由尖括号括起的状态名称.
在上面的例子中,"PHP"是状态."PHP_TOKEN"和"HTML_TOKEN"是yacc文件定义的_%token_s.