2017 © Pedro Peláez
 

library laiz-parsec

Parser Combinator

image

laiz/laiz-parsec

Parser Combinator

  • Friday, February 17, 2017
  • by nishimura
  • Repository
  • 2 Watchers
  • 0 Stars
  • 23 Installations
  • PHP
  • 0 Dependents
  • 0 Suggesters
  • 0 Forks
  • 0 Open issues
  • 7 Versions
  • 0 % Grown

The README.md

Laiz Parsec

Build Status Coverage Status Code Climate, (*1)

Latest Stable Version License, (*2)

String Parser

require 'vendor/autoload.php';

use Laiz\Func\Either;
use Laiz\Parsec;
use function Laiz\Parsec\parse;
use function Laiz\Parsec\str;

$parser = str('abc');

$ret = parse($parser, "Test", "abcdef");
var_dump($ret);
// Right abc

Combinator

require 'vendor/autoload.php';

use Laiz\Func\Either;
use Laiz\Parsec;
use function Laiz\Func\Applicative\const1;
use function Laiz\Parsec\parse;
use function Laiz\Parsec\satisfy;
use function Laiz\Parsec\flat;
use function Laiz\Parsec\many1;
use function Laiz\Parsec\endBy1;
use function Laiz\Parsec\char;
use function Laiz\Parsec\str;
use function Laiz\Parsec\eof;

$alnum = satisfy(function($s){
    return ctype_alnum($s);
});
$p = flat(many1($alnum));
$ret = parse($p, "Test", "abc,A03,zzz,@a");
var_dump($ret);
// Right "abc"

$p1 = endBy1($p, char(','));
$ret = parse($p1, "Test", "abc,A03,zzz,@a");
var_dump($ret);
// Right ["abc", "A03", "zzz"]

$p = eof();
$ret = parse($p, "Test", "abc");
var_dump($ret);
// Left ParseError

$p = eof();
$ret = parse($p, "Test", "");
var_dump($ret);
// Right Unit

$p = const1(str('abc'), eof()); // string "abc" *> eof
$ret = parse($p, "Test", "abc");
var_dump($ret);
// Right "abc"

$ret = parse($p, "Test", "abcd");
var_dump($ret);
// Left ParseError

HTML Parser

require 'vendor/autoload.php';

use Laiz\Func\Either;
use Laiz\Parsec;
use function Laiz\Func\Applicative\pure;
use function Laiz\Parsec\parse;
use function Laiz\Parsec\tryP;
use function Laiz\Parsec\satisfy;
use function Laiz\Parsec\anyChar;
use function Laiz\Parsec\flat;
use function Laiz\Parsec\many;
use function Laiz\Parsec\many1;
use function Laiz\Parsec\char;
use function Laiz\Parsec\str;
use function Laiz\Parsec\choice;
use function Laiz\Parsec\between;
use function Laiz\Parsec\notFollowedBy;
use function Laiz\Parsec\parserReturn;
use function Laiz\Parsec\sepEndBy;
use function Laiz\Parsec\Show\show;

class Attr
{
    public $name;
    public $value;
    public function __construct($n, $v){
        $this->name = $n;
        $this->value = $v;
    }
}
class TagInfo
{
    public $name;
    public $attrs = [];
    public function __construct($n, $a = []){
        $this->name = $n;
        $this->attrs = $a;
    }
}
class Tag
{
    public $name;
    public $attrs = [];
    public $children = [];
    public function __construct($i, $c = []){
        $this->name = $i->name;
        $this->attrs = $i->attrs;
        $this->children = $c;
    }
}
class Plain
{
    public $content;
    public function __construct($c){
        $this->content = $c;
    }
}

$html = '





';

function not($n){
    return satisfy(function($s) use ($n){
        return $s !== $n;
    });
}
function alnum(){
    return satisfy(function($s){
        return ctype_alnum($s);
    });
}
function space(){
    return satisfy(function($s){
        return strpos(" \r\n\t", $s) !== false;
    });
}
function spaces(){ return flat(many(space())); }
function spaces1(){ return flat(many1(space())); }


// Parser s u Tag
function tag(){
    $attrName = flat(many1(alnum()));
    $eq = char('=');
    $attrValue = between(char('"'), char('"'),
                         flat(many1(not('"'))));
    $attr = $attrName->bind(function($name) use ($eq, $attrValue){
        return $eq->const2($attrValue)->bind(function($value) use ($name){
            return parserReturn(new Attr($name, $value));
        });
    });
    //var_dump(parse($attr, "Test", 'foo="bar1">'));


    $tagName = flat(many1(alnum()))->const1(spaces());
    $tagContent = $tagName->bind(function($name) use ($attr){
        return sepEndBy($attr, spaces1())->bind(function($attrs) use ($name){
            return parserReturn(new TagInfo($name, $attrs));
        });
    });
    $tagOpen = between(char('<'), char('>'), $tagContent);
    //var_dump(parse($tagOpen, "Test", '<span>'));
    //var_dump(parse($tagOpen, "Test", '<span class="bar1" style="display:inline;">'));
    return $tagOpen->bind(function($info){
        return many(context())->bind(function($context) use ($info){
            $tagClose = str('</' . $info->name . '>');
            return $tagClose->bind(function($_) use ($info, $context){
                return parserReturn(new Tag($info, $context));
            });
        });
    });
}

// Parser s u Plain
function plain(){
    return flat(many1(not('<')))->bind(function($plain){
        return parserReturn(new Plain($plain));
    });
}
// Parser s u (Tag|Plain)
function context(){
    return spaces()->const2(choice([plain(), tryP(tag())]))->const1(spaces());
}
//var_dump(parse(tag(), "Test", '<div>test</div>'));
//var_dump(parse(many1(context()), "Test", 'aa

test
')); $parser = many1(context()); $ret = parse($parser, "Test", $html); $ret->either(function($left){ var_dump(show($left)); }, function($right){ var_dump($right); }); /* array(1) { [0] => class Tag#835 (3) { public $name => string(3) "div" public $attrs => array(0) { } public $children => array(2) { [0] => class Tag#6817 (3) { public $name => string(1) "a" public $attrs => array(1) { [0] => class Attr#4598 (2) { public $name => string(4) "href" public $value => string(14) "/user/info.php" } } public $children => array(1) { [0] => class Plain#6263 (1) { public $content => string(9) "User Info" } } } [1] => class Tag#2002 (3) { public $name => string(1) "a" public $attrs => array(2) { [0] => class Attr#7011 (2) { public $name => string(4) "href" public $value => string(7) "/admin/" } [1] => class Attr#5179 (2) { public $name => string(5) "class" public $value => string(3) "btn" } } public $children => array(1) { [0] => class Plain#2864 (1) { public $content => string(5) "Admin" } } } } } } */

The Versions

17/02 2017

dev-master

9999999-dev https://github.com/nishimura/laiz-parsec

Parser Combinator

  Sources   Download

MIT

The Requires

 

The Development Requires

by Satoshi Nishimura

parser functional monad combinator

17/02 2017

v0.1.4

0.1.4.0 https://github.com/nishimura/laiz-parsec

Parser Combinator

  Sources   Download

MIT

The Requires

 

The Development Requires

by Satoshi Nishimura

parser functional monad combinator

11/07 2016

v0.1.3

0.1.3.0 https://github.com/nishimura/laiz-parsec

Parser Combinator

  Sources   Download

MIT

The Requires

 

The Development Requires

by Satoshi Nishimura

parser functional monad combinator

09/07 2016

v0.1.2

0.1.2.0 https://github.com/nishimura/laiz-parsec

Parser Combinator

  Sources   Download

MIT

The Requires

 

The Development Requires

by Satoshi Nishimura

parser functional monad combinator

09/07 2016

v0.1.1

0.1.1.0 https://github.com/nishimura/laiz-parsec

Parser Combinator

  Sources   Download

MIT

The Requires

 

The Development Requires

by Satoshi Nishimura

parser functional monad combinator

09/07 2016

v0.1.0

0.1.0.0 https://github.com/nishimura/laiz-parsec

Parser Combinator

  Sources   Download

MIT

The Requires

 

The Development Requires

by Satoshi Nishimura

parser functional monad combinator

07/07 2016

v0.0.1

0.0.1.0 https://github.com/nishimura/laiz-parsec

Parser Combinator

  Sources   Download

MIT

The Requires

 

The Development Requires

by Satoshi Nishimura

parser functional monad combinator