作为宠物项目,我想尝试实现我自己设计的基本语言,可以用作网络脚本语言。将C ++程序作为Apache CGI运行是微不足道的,因此真正的工作在于如何解析包含非代码(HTML / CSS标记)和服务器端代码的输入文件。

在我的本科编译课程中,我们使用了 Flex Bison 为简单语言生成扫描程序和解析器。我们得到了一份语法副本,并编写了一个解析器,将简单语言翻译成虚拟机的简单程序集。 flex扫描器将输入标记化,并将标记传递给Bison解析器。

与我想做的事情之间的区别在于,与PHP一样,这种语言可以使用纯HTML标记,并且脚本语言散布如下:

<p>Hello,
<? echo "World ?>
</p>

我认为解析输入文件效率如下是错误的:

  1. 扫描输入,直到找到脚本开始标记('
  2. 第二个扫描程序标记输入文件的服务器端脚本部分(来自打开的标记:'')并将令牌传递给解析器,解析器无需知道文件中的标记。
  3. 控制权返回到第一个继续此常规模式的扫描程序。
  4. 基本上,第一个扫描程序仅区分Markup(直接返回到未修改的浏览器)和代码,代码传递给第二个扫描程序,后者又将代码标记化并将标记传递给解析器。

    如果是一个可靠的设计模式,PHP等语言如何有效地处理扫描输入和解析代码?

有帮助吗?

解决方案

你想看一下开始条件。例如:

"<?"            { BEGIN (PHP); }
<PHP>[a-zA-Z]*  { return PHP_TOKEN; }
<PHP>">?"       { BEGIN (0); }
[a-zA-Z]*       { return HTML_TOKEN; }

从状态0开始,使用BEGIN宏来改变状态。 要仅在特定状态下匹配RE,请在RE前面加上由尖括号括起的状态名称。

在上面的示例中,“PHP”表示“PHP”。是国家。 &QUOT; PHP_TOKEN&QUOT;和“HTML_TOKEN”是您的yacc文件定义的_%token_s。

其他提示

PHP不区分扫描和标记。它只是在标记模式下输出到缓冲区,然后在代码模式下切换到解析。您不需要双通扫描仪,只需一个flex lexer即可完成此操作。

如果您对PHP本身如何工作感兴趣,请下载源代码(尝试PHP4源代码,它更容易理解)。您想要查看的是Zend目录, zend_language_scanner.l

自己写了类似的东西,我真的建议重新考虑去Flex和Bison的路线,然后选择现代的东西,如 ANTLR的。它更容易理解(在lex语法中使用的宏变得非常混乱和难以阅读)并且它有一个内置的调试器( AntlrWorks )因此您不必花费数小时查看3 Meg调试文件。它还支持多种语言(Java,c#,C,Python,Actionscript),并且拥有一本优秀的书籍和一个非常好的网站,应该能够让您立即启动并运行。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top