php 解析器模式,娓娓道来:解析器模式-interpreter

本文通过一个示例介绍了如何使用解析器模式来解析类似PHP的脚本语言。具体展示了如何创建表达式基类、文字扩展、变量和布尔表达式扩展,以及如何实现等号、或和与操作符。通过示例代码解释了如何解析并执行表达式,输出不同的结果。文章以MarkLogic语言为例,探讨了面向对象编程在解析语言中的应用。
摘要由CSDN通过智能技术生成

解析器模式:解析脚本的语言解析器。

php源于c语言,其实是用c语言解析了php脚本,那么php有是如何解析其他语言的呢,看看面向对象的魅力所在吧。

现在解析这样一句话:

$input equals "4" or $input equals "four"

$input是变量,equals是等于操作符,or和and是布尔操作符。这个语言成为MarkLogic。这里不讨论输入的问题,只讨论这句话的输出问题

首先创建一个表达式基类

abstract class Expression{

private static $keycount=0;

private $key;

abstract function interpret(InterpreterContext $content);

function getKey()

{

if( !isset($this->key))

{

self::$keycount++;

$this->key = self::$keycount;

}

return $this->key;

}

}

然后做文字扩展和解析器

class LiteralExpression extends Expression{

private $value;

function __construct( $value )

{

$this->value = $value;

}

function interpret(InterpreterContext $content){

$content->replace($this,$this->value);

}

}

class InterpreterContext{

private $expressionstore = array();

function replace(Expression $exp,$value)

{

$this->expressionstore[$exp->getKey()]=$value;

$this->expressionstore[$exp->getKey()]."\n";

}

function lookup(Expression $exp)

{

return $this->expressionstore[$exp->getKey()];

}

}

然后做变量和布尔表达式扩展

class VariableExpression extends Expression{

private $name;

private $val;

function __construct($name,$val=null)

{

$this->name = $name;

$this->val = $val;

}

function interpret(InterpreterContext $context){

if(! is_null($this->val))

{

$context->replace($this,$this->val);

$this->val = null;

}

}

function setValue($value)

{

$this->val = $value;

}

function getKey(){

return $this->name;

}

}

abstract class OperatorExpression extends Expression{

protected $l_op;

protected $r_op;

function __construct(Expression $lp,Expression $rp)

{

$this->l_op = $lp;

$this->r_op = $rp;

}

function interpret(InterpreterContext $context){

$this->l_op->interpret($context);

$this->r_op->interpret($context);

$result_l = $context->lookup($this->l_op);

$result_r = $context->lookup($this->r_op);

$this->doInterpret($context,$result_l,$result_r);

}

protected abstract function doInterpret(InterpreterContext $context,

$result_l,

$result_r);

}

class EqualsExpression extends OperatorExpression{

protected function doInterpret(InterpreterContext $context, $result_l, $result_r){

$context->replace($this,$result_l == $result_r);

}

}

class BoolOrExpression extends OperatorExpression{

protected function doInterpret(InterpreterContext $context, $result_l, $result_r){

$context->replace($this,$result_l || $result_r);

}

}

class BoolAndExpression extends OperatorExpression{

protected function doInterpret(InterpreterContext $context, $result_l, $result_r){

$context->replace($this,$result_l && $result_r);

}

}

下面运行一下:

$context = new InterpreterContext();

$input = new VariableExpression('input');

$statement = new BoolOrExpression(new  EqualsExpression( $input,new LiteralExpression('four')), new  EqualsExpression( $input,new LiteralExpression('4')));

foreach(array('four','4','52') as $val){

$input->setValue($val);

print "$val:\n";

$statement->interpret( $context );

if($context->lookup($statement)){

print "top marks\n\n";

} else{

print "dunce hat on\n\n";

}

}

结果如下:

four:

top marks

4:

top marks

52:

dunce hat on

其中array('four','4','52')分别作为input的value,和LiteralExpression比较,如果有问题讨论就可以私聊

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是一个早期的 PHP 解析器,相当于实现了 PHPPHP 脚本的解析。示例代码:<?php // Autoload required classes require "vendor/autoload.php"; // Instantiate new parser instance $parser = new PhpParser\Parser(); // Return and print an AST from string contents $astNode = $parser->parseSourceFile('<?php /* comment */ echo "hi!"'); var_dump($astNode); // Gets and prints errors from AST Node. The parser handles errors gracefully, // so it can be used in IDE usage scenarios (where code is often incomplete). $errors = PhpParser\Utilities::getDiagnostics($astNode); var_dump(iterator_to_array($errors)); // Traverse all Node descendants of $astNode foreach ($astNode->getDescendantNodes() as $descendant) {     if ($descendant instanceof \PhpParser\Node\StringLiteral) {         // Print the Node text (without whitespace or comments)         var_dump($descendant->getText());         // All Nodes link back to their parents, so it's easy to navigate the tree.         $grandParent = $descendant->getParent()->getParent();         var_dump($grandParent->getNodeKindName());         // The AST is fully-representative, and round-trippable to the original source.         // This enables consumers to build reliable formatting and refactoring tools.         var_dump($grandParent->getLeadingCommentAndWhitespaceText());     }     // In addition to retrieving all children or descendants of a Node,     // Nodes expose properties specific to the Node type.     if ($descendant instanceof \PhpParser\Node\Expression\EchoExpression) {         $echoKeywordStartPosition = $descendant->echoKeyword->getStartPosition();         // To cut down on memory consumption, positions are represented as a single integer          // index into the document, but their line and character positions are easily retrieved.         $lineCharacterPosition = \PhpParser\Utilities::getLineCharacterPositionFromPosition(             $echoKeywordStartPosition         );         echo "line: $lineCharacterPosition->line, character: $lineCharacterPosition->character";     } } 标签:Tolerant
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值