这篇博文最好以其原始格式查看。
这篇文章回顾了题为一小时表达语言的演示,回顾了概念和代码。1
表达式语言2,在此上下文中,计算表达式 - 字节序列,很可能是 UTF-8 字符。3 示例包括:
1 1
//article[@title="foobar"]//image
.items[].foo|select(.bar = "foo")
a.comments > 1 and a.category not in ["misc"]
表达式语言(或 DSL4)的示例是:
- JQ
- Kibana 查询语言
- XPath 语言
- Symfony 表达语言
为什么要构建自己的表达语言? 为什么不呢? 太忙? 不用担心!它不需要几个月、几周甚至几天。 使用一小时表达语言在一小时内创建一个!5
ProCalc2000
我们将构建 ProCalc2000 表达式语言 - 2000 年及以后的下一代非科学算术计算器。
它评估诸如 1 1
或 1 2
之类的表达式,并且可以处理诸如 1 3 2 / 2
.
哥斯拉
由于浮点数,哥斯拉不喜欢除法。该语言包含数字(例如 1、2)和运算符(、-、)。 它不会*支持运算符优先级(参见附录一)或除法。
尽管它很简单,但它为添加功能提供了基础:变量、函数、管道运算符、后缀、字符串连接,甚至(违背哥斯拉的意愿)除法。
请问,One 里有什么?
评估字节序列的方法有很多,但我们将使用分词器、解析器和评估器:
<code> +-----------+ tokens +--------+ ast +-----------+ EXPRESSION ==>| Tokenizer |--------->| Parser |------>| Evaluator | => VALUE +-----------+ +--------+ +-----------+</code>
分词器
也称为词法分析器或扫描器。此类将字符串拆分为称为标记的分类块。
class Tokenizer { public function tokenize(string $expression): Tokens { // ... } }
例如,1 2 3
产生五个标记:
<code>Token(Integer, 1) Token(Plus) Token(Integer, 2) Token(Plus) Token(Integer, 3)</code>
分词器从左到右扫描,识别有趣的块:正整数以及 、 - 和 * 运算符。空白被忽略;其他字符会导致错误。 令牌类型有整数、加号、减号和乘号。
哥斯拉
哥斯拉建议使用分词器和堆栈机,但我们将使用解析器和评估器,因为哥斯拉关心。分词器不检查表达式的有效性;它仅对块进行分类。6 标记将传递给解析器。
解析器
解析器解释标记,将它们转换为抽象语法树(AST)。
<code> +-----------+ tokens +--------+ ast +-----------+ EXPRESSION ==>| Tokenizer |--------->| Parser |------>| Evaluator | => VALUE +-----------+ +--------+ +-----------+</code>
给定一个标记列表,解析器返回一个 AST——树的根节点。 每个节点都是一个可评估的表达式;节点类型有 BinaryOp 和 Integer。
二元运算有两个操作数(例如,
foo or bar
可以是BinaryOp(Variable('foo'), 'or', Variable('bar'))
)。一元运算有一个操作数(例如,
-1
)。三元运算有三个操作数(例如,
foo ? bar : baz
)。
表达式1 1 / 5
是一个以
为运算符的BinaryOp,一个操作数为1,另一个为另一个BinaryOp(1 / 5
)。
class Tokenizer { public function tokenize(string $expression): Tokens { // ... } }
评估者
求值器接受一个 Node 并返回一个值(这里是一个整数)。 这是一个树行走翻译器。
<code>Token(Integer, 1) Token(Plus) Token(Integer, 2) Token(Plus) Token(Integer, 3)</code>
请显示您的代码?
此代码源自 PHPSW 聚会,由单元测试驱动(此处省略)。查看存储库。
哥斯拉
哥斯拉会对这段代码感到愤怒并建议重构。分词器
首先,一个带有 Token
枚举和可选值的 TokenType
类:
class Parser { public function parse(Tokens $tokens): Node { // ... } }
<code> +-------------+ | Binary Op + | <p>In PHP:</p> ```php $ast = new BinaryOp( left: new Integer(1), operator: '+', right: new BinaryOp( left: new Integer(1), operator: '/', right: new Integer(5), ) );</code>
令牌看起来像:
class Evaluator { public function evaluate(Node $node): int { // ... } }
Tokenizer
类完成以下工作:7
class Token { public function __construct( public TokenType $type, public ?string $value = null ) {} }
Tokens
系列:
enum TokenType { case Plus; case Minus; case Multiply; case Integer; }
哥斯拉
Godzilla 更喜欢使用数组和 array_shift 或生成器来同时进行标记化和解析。解析器
[ new Token(TokenType::Integer, 50), new Token(TokenType::Plus), // ... ]
这是添加运算符优先级、后缀解析和管道运算符的地方。 例如,后缀解析可以处理“5 英里”这样的表达式。
评估者
class Tokenizer { public function tokenize(string $expression): Tokens { $offset = 0; $tokens = []; while (isset($expression[$offset])) { $char = $expression[$offset++]; if (is_numeric($char)) { while (is_numeric($expression[$offset] ?? null)) { $char .= $expression[$offset++]; } $tokens[] = new Token(TokenType::Integer, $char); continue; } $token = match ($char) { '+' => new Token(TokenType::Plus), '-' => new Token(TokenType::Minus), '*' => new Token(TokenType::Multiply), ' ' => null, default => throw new RuntimeException(sprintf( 'Invalid operator: "%s"', $char )), }; if ($token === null) { continue; } $tokens[] = $token; } return new Tokens($tokens); } }
就是这样
此代码是实时编码的,包括测试。 完整的代码可以在存储库中找到。
运算符优先级
表达式 1 * 3 4
应该是 (1 * 3) 4 = 7
,但由于解析方法,我们的语言将其计算为 1 * (3 4) = 7
。8 Pratt 解析器纠正了这一点:
<code> +-----------+ tokens +--------+ ast +-----------+ EXPRESSION ==>| Tokenizer |--------->| Parser |------>| Evaluator | => VALUE +-----------+ +--------+ +-----------+</code>
哥斯拉
哥斯拉了解递归。延伸阅读
- 制作口译员:罗伯特·尼斯特罗姆 (Robert Nystrom) 所著的书籍(免费网络版)
- 表达式解析变得简单:Robert Nystrom 的博客文章
- 堆栈机 RPN 计算器:2014 年 Igor Wiedler 发表
- 学说词法分析器
- PHPStan Phpdoc 解析器9
- 代码随着每次迭代而变化。
- 或更具体地说,是一个表达式语言解释器。
- 在 PHP 中通常称为字符串。
- 领域特定语言。
- 不存在专利。
- 分词器对于语法突出显示很有用。
-
preg_
方法可能会更高效。 - 只有在期望不同的答案时才是错误的。
- 树遍历是通过 Doctrine 的查询构建器发现的。
以上是一小时表达语言的详细内容。更多信息请关注PHP中文网其他相关文章!

PHP类型提示提升代码质量和可读性。1)标量类型提示:自PHP7.0起,允许在函数参数中指定基本数据类型,如int、float等。2)返回类型提示:确保函数返回值类型的一致性。3)联合类型提示:自PHP8.0起,允许在函数参数或返回值中指定多个类型。4)可空类型提示:允许包含null值,处理可能返回空值的函数。

PHP中使用clone关键字创建对象副本,并通过\_\_clone魔法方法定制克隆行为。1.使用clone关键字进行浅拷贝,克隆对象的属性但不克隆对象属性内的对象。2.通过\_\_clone方法可以深拷贝嵌套对象,避免浅拷贝问题。3.注意避免克隆中的循环引用和性能问题,优化克隆操作以提高效率。

PHP适用于Web开发和内容管理系统,Python适合数据科学、机器学习和自动化脚本。1.PHP在构建快速、可扩展的网站和应用程序方面表现出色,常用于WordPress等CMS。2.Python在数据科学和机器学习领域表现卓越,拥有丰富的库如NumPy和TensorFlow。

HTTP缓存头的关键玩家包括Cache-Control、ETag和Last-Modified。1.Cache-Control用于控制缓存策略,示例:Cache-Control:max-age=3600,public。2.ETag通过唯一标识符验证资源变化,示例:ETag:"686897696a7c876b7e"。3.Last-Modified指示资源最后修改时间,示例:Last-Modified:Wed,21Oct201507:28:00GMT。

在PHP中,应使用password_hash和password_verify函数实现安全的密码哈希处理,不应使用MD5或SHA1。1)password_hash生成包含盐值的哈希,增强安全性。2)password_verify验证密码,通过比较哈希值确保安全。3)MD5和SHA1易受攻击且缺乏盐值,不适合现代密码安全。

PHP是一种服务器端脚本语言,用于动态网页开发和服务器端应用程序。1.PHP是一种解释型语言,无需编译,适合快速开发。2.PHP代码嵌入HTML中,易于网页开发。3.PHP处理服务器端逻辑,生成HTML输出,支持用户交互和数据处理。4.PHP可与数据库交互,处理表单提交,执行服务器端任务。

PHP在过去几十年中塑造了网络,并将继续在Web开发中扮演重要角色。1)PHP起源于1994年,因其易用性和与MySQL的无缝集成成为开发者首选。2)其核心功能包括生成动态内容和与数据库的集成,使得网站能够实时更新和个性化展示。3)PHP的广泛应用和生态系统推动了其长期影响,但也面临版本更新和安全性挑战。4)近年来的性能改进,如PHP7的发布,使其能与现代语言竞争。5)未来,PHP需应对容器化、微服务等新挑战,但其灵活性和活跃社区使其具备适应能力。

PHP的核心优势包括易于学习、强大的web开发支持、丰富的库和框架、高性能和可扩展性、跨平台兼容性以及成本效益高。1)易于学习和使用,适合初学者;2)与web服务器集成好,支持多种数据库;3)拥有如Laravel等强大框架;4)通过优化可实现高性能;5)支持多种操作系统;6)开源,降低开发成本。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

适用于 Eclipse 的 SAP NetWeaver 服务器适配器
将Eclipse与SAP NetWeaver应用服务器集成。

安全考试浏览器
Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

Atom编辑器mac版下载
最流行的的开源编辑器

Dreamweaver CS6
视觉化网页开发工具

Dreamweaver Mac版
视觉化网页开发工具