2019年2月20日09:18:22

AST语法树自己写代码解析的话就比较麻烦,有现成的库可以解析PHP,就像webpack就是自己解析js的语法代码,编译成各种版本的可用代码

github https://github.com/josdejong/mathjs

Extension Description
mathsteps A step-by-step math solver library that is focused on pedagogy (how best to teach). The math problems it focuses on are pre-algebra and algebra problems involving simplifying expressions.
mathjs‑expression‑parser This custom build of mathjs contains just the expression parser and basic arithmetic functions for numbers. About four times as small as the full mathjs library.
mathjs-simple-integral Extends Math.js to be able to compute simple integrals.
math.diff.js Symbolic differentiation plugin for Math.js
postcss-math PostCSS plugin for making calculations with math.js

没有办法,自己去实现  前缀,中缀,后缀表达式来实现解析字符串,对于简单的加减乘除都是比较容易的,但是需要支持一些复杂一点逻辑的计算就比较麻烦,比如开方,乘方等

其他一些解析工具基本都是java ,c,cpp的

又尝试找了一些工具,发现JavaScript里面有一些,但是不符合我的个人需求,但是可以满足大部分,简单数学字符数解析和计算

http://mathjs.org

PHP可用的库

composer require nikic/php-parser

一直在更新可以使用

namespace App\Http\Controllers\Data\V2;

use App\Http\Controllers\Data\V2\BaseController as Base;

use PhpParser\Error;
use PhpParser\NodeDumper;
use PhpParser\ParserFactory; class CommonController extends Base { public static function index(Request $Request) {
$code = <<<CODE
<?php
((99 + 1)*4-1);
CODE;
$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
try {
$ast = $parser->parse($code);
} catch (Error $error) {
echo "Parse error: {$error->getMessage()}\n";
return;
} $dumper = new NodeDumper;
echo $dumper->dump($ast);

结果

我是使用pre打印的

array(
0: Stmt_Expression(
expr: Expr_BinaryOp_Minus(
left: Expr_BinaryOp_Mul(
left: Expr_BinaryOp_Plus(
left: Scalar_LNumber(
value: 99
)
right: Scalar_LNumber(
value: 1
)
)
right: Scalar_LNumber(
value: 4
)
)
right: Expr_BinaryOp_Plus(
left: Scalar_LNumber(
value: 1
)
right: Scalar_LNumber(
value: 2
)
)
)
)
)

基本就可以达到语法树解析,元素自己解析就可以了,但是支持的运算符只能支持官方已有的运算符,特殊的运算符或者自定义的运算符,得自己标记去解析,特别复杂的需要自己根据解析的ast去重新转换成自己实际业务的需求

如果你需要添加一个vistor 遍历真个ast树 ,并获取,修改数据

<?php

namespace App\Service;

use PhpParser\NodeVisitorAbstract;
use PhpParser\Node; class Visitor extends NodeVisitorAbstract { public $data;
public $operator; public function __construct() {
$this->data = new \SplStack();
$this->operator = new \SplStack();
} public function leaveNode(Node $node) {
//所有的符号
if ($node instanceof Node\Expr) {
$this->operator->push($node->getType());
}
//所有运算符
// if ($node instanceof Node\Expr\BinaryOp) {
// $this->operator->push($node->getType());
// }
// $this->operator->push($node->getType());
if ($node instanceof Node\Scalar) {
$this->data->push((string) $node->value);
}
} public function getData() {
return $this->data;
} public function getOperator() {
return $this->operator;
} }

然后在解析ast树的代码添加vistor

   public function TransformToAst($string = '') {
try {
if (empty($string)) {
throw new \Exception('公式不能为空');
}
$code = <<<CODE
<?php
$string;
CODE;
$ParserFactory = new ParserFactory();
$parser = $ParserFactory->create(ParserFactory::PREFER_PHP7);
$ast = $parser->parse($code); $traverser = new NodeTraverser;
$Visitor = new Visitor();
$traverser->addVisitor($Visitor); $modifiedStmts = $traverser->traverse($ast);
p($Visitor->getOperator());
pp($Visitor->getData());
// pp($modifiedStmts);
//
die; if (empty($ast_object)) {
throw new \Exception('解析表达式为空');
}
$ast_new = self::ParseAstToArray($ast_object['0']);
return $ast_new;
} catch (\Exception $e) {
throw new \Exception($e->getMessage() . $e->getFile() . $e->getLine());
}
}

其他提供的很多工具类,但是缺少demo实例,让处入手的人很难直接上手使用

参考 https://github.com/nikic/PHP-Parser/blob/master/doc/component/Walking_the_AST.markdown 以后有时间在翻译一下文档

Microsoft/tolerant-php-parser

这个微软的库

解析数学表达式 代码解析AST语法树的更多相关文章

  1. Vue源码解析:AST语法树转render函数

    开始 今天要说的代码全在codegen文件夹中,在说实现原理前,还是先看个简单的例子! <div class="container"> <span>{{ms ...

  2. 机器学习完整过程案例分布解析,python代码解析

    所谓学习问题,是指观察由n个样本组成的集合,并依据这些数据来预測未知数据的性质. 学习任务(一个二分类问题): 区分一个普通的互联网检索Query是否具有某个垂直领域的意图.如果如今有一个O2O领域的 ...

  3. C++实现对数学基本运算表达式的解析

    代码地址如下:http://www.demodashi.com/demo/11078.html 前段时间在LeetCode上刷题,遇到了很多涉及对字符串进行解析的题目.可能是出于这个原因,最近迷恋上了 ...

  4. Babel(抽象语法树,又称AST)

    文章:https://juejin.im/post/5a9315e46fb9a0633a711f25 https://github.com/jamiebuilds/babel-handbook/blo ...

  5. 笔记-爬虫-js代码解析

    笔记-爬虫-js代码解析 1.      js代码解析 1.1.    前言 在爬取网站时经常会有js生成关键信息,而且js代码是混淆过的. 以瓜子二手车为例,直接请求https://www.guaz ...

  6. 基于语法分析器GOLD Parser开发的数学表达式计算器

    最近发现一款文法分析神器,看完官网(http://goldparser.org/)的介绍后感觉很犀利的样子,于是就拿来测试了一番,写了一个数学表达式分析的小程序,支持的数学运算符如下所示:常规运算:+ ...

  7. 抽象语法树 Abstract syntax tree

    什么是抽象语法树? 在计算机科学中,抽象语法和抽象语法树其实是源代码的抽象语法结构的树状表现形式 在线编辑器 我们常用的浏览器就是通过将js代码转化为抽象语法树来进行下一步的分析等其他操作.所以将js ...

  8. WHY数学表达式的3D可视化

    WHY数学表达式的3D可视化 很早之前我就有这种想法,将数学表达式的图形显示出来.最近终于实现了这套较为完善的版本,将其代码公布,也为开源做点贡献.首先系统中定义一套脚本语言格式,用于描述数学表达式. ...

  9. JavaScript的工作原理:解析、抽象语法树(AST)+ 提升编译速度5个技巧

    这是专门探索 JavaScript 及其所构建的组件的系列文章的第 14 篇. 如果你错过了前面的章节,可以在这里找到它们: JavaScript 是如何工作的:引擎,运行时和调用堆栈的概述! Jav ...

随机推荐

  1. -bash: Chmod: command not found

    是增加该文件的所有者拥有运行权限 如果所有者是root ,还要加sudo chmod u+x drlinuxclient.bin (sudo) chmod u+x drlinuxclient.bin ...

  2. Maven 构建浏览器解析userAgent类

    创建Maven项目 添加pom.xml 依赖 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=&qu ...

  3. Leetcode#88. Merge Sorted Array(合并两个有序数组)

    题目描述 给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组. 说明: 初始化 nums1 和 nums2 的元素数量分别为 m ...

  4. JS中some(),every(),forEach(),map(),filter()区别

    JS在1.6中为Array新增了几个方法map(),filter(),some(),every(),forEach(),也就是一共有这么多方法了. 刚开始接触这些倒也记得不是很清楚,在此纪录一下以加深 ...

  5. jquery.ajax()详解

    jQuery.ajax() 函数详解 traditional 如果你希望使用传统方式来序列化参数,将该属性设为true. 传递数组时, traditional必须为true var arr = []; ...

  6. C#任务同步

    using System; using System.Diagnostics; using System.Threading; using System.Threading.Tasks; using ...

  7. 【转】使用keepalived设置虚拟IP示例

    准备 准备两台机器,IP地址信息如下: host1: 192.168.56.103 host2: 192.168.56.104 为了测试需要,分别在两台机器上安装apache并启动httpd服务,使下 ...

  8. fiddler启用过滤规则只显示想要的接口数据

    fiddler启用过滤规则只显示想要的接口数据 比如只显示192.168.11.80站点数据 点击应用规则就可以只显示192.168.11.80了

  9. 随机获取min和max之间的一个整数

    // 随机获取min和max之间的一个整数 const randomNum = (Min, Max) => { let Range = Max - Min; let Rand = Math.ra ...

  10. All about Using Burp Suite

    1.how  to use burpsuite I can't thank them enough for allowing us to test web application ,making su ...