0

0

解析转换器3:手写PHP转Python编译器的词法部分

高洛峰

高洛峰

发布时间:2017-03-12 10:17:00

|

1463人浏览过

|

来源于php中文网

原创

这篇文章解析转换器3:手写php转python编译器的词法部分

一时技痒,自然而然地想搞个大家伙,把整个PHP程序转成Python。不比模板,可以用正则匹配偷懒,这次非写一个Php编译器不可。

上网搜了一下,发现大部分Python to xxx的transpile都是直接基于AST,省略了最重要的Tokenizer,Parser。直接写个Visitor了事。要不然就是基于Antlr之类的生成器,搞一大堆代码,看得令人心烦。

既然大家都不想做这个苦力,我就来试试,手工写一个Php编译器。分Tokenizer,Parser,Visitor三个部分来实现。

翻出《龙书》《虎书》做参考,仔细学了一回PHP,不学不知道,原来PHP有那么多特性,做个编译器真心累人。

立即学习PHP免费学习笔记(深入)”;

易标AI
易标AI

告别低效手工,迎接AI标书新时代!3分钟智能生成,行业唯一具备查重功能,自动避雷废标项

下载

词法部分很简单,就是一个自动机。设计了一个结构存放自动机,然后简单粗暴地在自动机上编程,也顾不上什么性能了,就是个一锤子买卖。

写得还算快,调试不是很顺,不过我是不会说的,哈

自动机不复杂,发上来大家看看,敬请指正。


self.statemachine = {
            'current': {
                'state': 'default', 'content': '', 'line': 0},
            'default': [
                {'name': 'open', 'next': 'php', 'extra': 0, 'start': 0, 'end': 0, 'cache': '',
                 'token': r'<\?'},
                {'name': 'open', 'next': 'php', 'extra': 0, 'start': 0, 'end': 0, 'cache': '',
                 'token': r'<\?php'}],
            'php': [
                {'name': 'close', 'next': 'default', 'extra': 0,
                 'token': r'\?>', 'start': 0, 'end': 0, 'cache': ''},
                {'name': 'lnum', 'next': '', 'extra': 0, 'start': 0, 'end': 0, 'cache': '',
                 'token': r'[0-9]+'},
                {'name': 'dnum', 'next': '', 'extra': 0, 'start': 0, 'end': 0, 'cache': '',
                 'token': r'([0-9]*\.[0-9]+)|([0-9]+\.[0-9]*)'},
                {'name': 'exponent', 'next': '', 'extra': 0, 'start': 0, 'end': 0, 'cache': '',
                 'token': r'(([0-9]+|([0-9]*\.[0-9]+)|([0-9]+\.[0-9]*))[eE][+-]?[0-9]+)'},
                {'name': 'hnum', 'next': '', 'extra': 0, 'start': 0, 'end': 0, 'cache': '',
                 'token': r'0x[0-9a-fA-F]+'},
                {'name': 'bnum', 'next': '', 'extra': 0, 'start': 0, 'end': 0, 'cache': '',
                 'token': r'0b[01]+'},
                {'name': 'label', 'next': '', 'extra': 0, 'start': 0, 'end': 0, 'cache': '',
                 'token': r'[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'},
                {'name': 'comment', 'next': 'commentline', 'extra': 1,
                 'token': r'//', 'start': 0, 'end': 0, 'cache': ''},
                {'name': 'comment', 'next': 'commentline', 'extra': 1,
                 'token': r'#', 'start': 0, 'end': 0, 'cache': ''},
                {'name': 'comment', 'next': 'comment', 'extra': 1,
                 'token': r'/\*', 'start': 0, 'end': 0, 'cache': ''},
                {'name': 'string', 'next': 'string1', 'extra': 1,
                 'token': r'\'', 'start': 0, 'end': 0, 'cache': ''},
                {'name': 'string', 'next': 'string2', 'extra': 1,
                 'token': r'"', 'start': 0, 'end': 0, 'cache': ''},
                {'name': 'symbol', 'next': '', 'extra': 0, 'start': 0, 'end': 0, 'cache': '',
                 'token': r'[\\\{\};:,\.\[\]\(\)\|\^&\+-/\*=%!~$<>\?@]'}],
            'string1': [
                {'name': 'string', 'next': 'php', 'extra': 0,
                 'token': r'\'', 'start': 0, 'end': 0, 'cache': ''},
                {'name': 'string', 'next': 'escape1', 'extra': 1,
                 'token': r'\\', 'start': 0, 'end': 0, 'cache': ''},
                {'name': 'string', 'next': '', 'extra': 1,
                 'token': r'', 'start': 0, 'end': 0, 'cache': ''}],
            'escape1': [
                {'name': 'string', 'next': 'string1', 'extra': 1,
                 'token': r'.', 'start': 0, 'end': 0, 'cache': ''}],
            'string2': [
                {'name': 'string', 'next': 'php', 'extra': 0,
                 'token': r'\'', 'start': 0, 'end': 0, 'cache': ''},
                {'name': 'string', 'next': 'escape2', 'extra': 1,
                 'token': r'\\', 'start': 0, 'end': 0, 'cache': ''},
                {'name': 'string', 'next': '', 'extra': 1,
                 'token': r'', 'start': 0, 'end': 0, 'cache': ''}],
            'escape2': [
                {'name': 'string', 'next': 'string2', 'extra': 1,
                 'token': r'.', 'start': 0, 'end': 0, 'cache': ''}],
            'commentline': [
                {'name': 'comment', 'next': 'php', 'extra': 0,
                 'token': r'(\r|\n|\r\n)', 'start': 0, 'end': 0, 'cache': ''},
                {'name': 'comment', 'next': 'php', 'extra': 0,
                 'token': r'', 'start': 0, 'end': 0, 'cache': ''}],
            'comment': [
                {'name': 'comment', 'next': 'php', 'extra': 0,
                 'token': r'\*/', 'start': 0, 'end': 0, 'cache': ''},
                {'name': 'comment', 'next': '', 'extra': 1,
                 'token': r'', 'start': 0, 'end': 0, 'cache': ''}]}

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
C++ 单元测试与代码质量保障
C++ 单元测试与代码质量保障

本专题系统讲解 C++ 在单元测试与代码质量保障方面的实战方法,包括测试驱动开发理念、Google Test/Google Mock 的使用、测试用例设计、边界条件验证、持续集成中的自动化测试流程,以及常见代码质量问题的发现与修复。通过工程化示例,帮助开发者建立 可测试、可维护、高质量的 C++ 项目体系。

6

2026.01.16

java数据库连接教程大全
java数据库连接教程大全

本专题整合了java数据库连接相关教程,阅读专题下面的文章了解更多详细内容。

27

2026.01.15

Java音频处理教程汇总
Java音频处理教程汇总

本专题整合了java音频处理教程大全,阅读专题下面的文章了解更多详细内容。

12

2026.01.15

windows查看wifi密码教程大全
windows查看wifi密码教程大全

本专题整合了windows查看wifi密码教程大全,阅读专题下面的文章了解更多详细内容。

35

2026.01.15

浏览器缓存清理方法汇总
浏览器缓存清理方法汇总

本专题整合了浏览器缓存清理教程汇总,阅读专题下面的文章了解更多详细内容。

5

2026.01.15

ps图片相关教程汇总
ps图片相关教程汇总

本专题整合了ps图片设置相关教程合集,阅读专题下面的文章了解更多详细内容。

8

2026.01.15

ppt一键生成相关合集
ppt一键生成相关合集

本专题整合了ppt一键生成相关教程汇总,阅读专题下面的的文章了解更多详细内容。

5

2026.01.15

php图片上传教程汇总
php图片上传教程汇总

本专题整合了php图片上传相关教程,阅读专题下面的文章了解更多详细教程。

2

2026.01.15

phpstorm相关教程大全
phpstorm相关教程大全

本专题整合了phpstorm相关教程汇总,阅读专题下面的文章了解更多详细内容。

4

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Python 教程
Python 教程

共137课时 | 7.4万人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.3万人学习

c语言项目php解释器源码分析探索
c语言项目php解释器源码分析探索

共7课时 | 0.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号