function __construct(HatenaSyntax_Locator $locator) { /* * 当該パーサへのディスパッチの試行は以下の順で行われる。 * ディスパッチが失敗した場合、次のディスパッチが試行される * * 1. lineTableからのディスパッチ * 2. paragraphCheckTableからのディスパッチ * 3. firstCharTableからのディスパッチ * 4. パラグラフ * */ $this->lineTable = array('' => $locator->emptyParagraph, '>>' => PEG::choice($locator->blockquote, $locator->paragraph), '>|' => PEG::choice($locator->pre, $locator->paragraph), '>||' => PEG::choice($locator->superpre, $locator->paragraph), '[:contents]' => $locator->tableOfContents, '====' => $locator->separator); // 行の最初の一文字が存在し、かつこの配列のキー以外だった場合 // 必ずパラグラフが来る $this->paragraphCheckTable = array(':' => true, '>' => true, '|' => true, '+' => true, '-' => true, '*' => true); $this->firstCharTable = array('*' => $locator->header, '+' => $locator->list, '-' => $locator->list, '|' => PEG::choice($locator->table, $locator->paragraph), ':' => PEG::choice($locator->definitionList, $locator->paragraph), '>' => PEG::choice($locator->superpre, $locator->blockquote, $locator->noParagraph, $locator->paragraph)); $this->paragraph = $locator->paragraph; }
<?php /** * 行頭に#があったら無視するパーサのサンプル */ include_once dirname(__FILE__) . '/../code/PEG.php'; $line = PEG::line(); $ignore = PEG::drop(PEG::andalso('#', $line)); $parser = PEG::join(PEG::many(PEG::choice($ignore, $line))); $context = PEG::context(' Lorem ipsum dolor sit amet, #consectetur adipisicing elit, #sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. '); var_dump($parser->parse($context)); /* 結果 string(64) " Lorem ipsum dolor sit amet, labore et dolore magna aliqua. " */
protected function createBracket() { return PEG::pack('[', PEG::choice($this->inlineTableOfContents, $this->nullLink, $this->keywordLink, $this->imageLink, $this->httpLink), ']'); }
*/ $t = new Benchmark_Timer(); $str = '((((((((1))))))))'; $t->start(); // メモ化していないパーサ $a = PEG::ref($a_ref); $p = PEG::ref($p_ref); $a_ref = PEG::choice(PEG::seq($p, '+', $a), PEG::seq($p, '-', $a), $p); $p_ref = PEG::choice(PEG::seq('(', $a, ')'), '1'); $a->parse(PEG::context($str)); $t->setMarker('no memoize'); // メモ化しているパーサ $a = PEG::ref($a_ref); $p = PEG::ref($p_ref); $a_ref = PEG::memo(PEG::choice(PEG::seq($p, '+', $a), PEG::seq($p, '-', $a), $p)); $p_ref = PEG::memo(PEG::choice(PEG::seq('(', $a, ')'), '1')); $a->parse($c = PEG::context($str)); $t->setMarker('memoize'); $t->stop(); $t->display(); /* 結果 --------------------------------------------------------- marker time index ex time perct --------------------------------------------------------- Start 1242400475.10093900 - 0.00% --------------------------------------------------------- no memoize 1242400476.30805000 1.207111 99.74% --------------------------------------------------------- memoize 1242400476.31115500 0.003105 0.26% --------------------------------------------------------- Stop 1242400476.31117700 0.000022 0.00%
protected function createBracket() { return PEG::pack('[', PEG::choice($this->imageLink, $this->httpLink), ']'); }
function __construct(PEG_IParser $bracket, PEG_IParser $footnote, PEG_IParser $inlinetag) { $this->table = array('[' => PEG::choice($bracket, PEG::anything()), '(' => PEG::choice($footnote, PEG::anything()), '<' => PEG::choice($inlinetag, PEG::anything())); }
public function __construct(PEG_IParser $element) { $open = PEG::second('<', PEG::choice('del', 'strong', 'ins', 'em'), '>'); $close = PEG::second('</', PEG::choice('del', 'strong', 'ins', 'em'), '>'); $this->parser = PEG::seq($open, PEG::many(PEG::subtract($element, $close)), $close); }
<?php include_once dirname(__FILE__) . '/t/t.php'; $t = new lime_test(); $p = PEG::seq('a', 'a'); $c = PEG::context(array('a', 'a')); $t->is($p->parse($c), array('a', 'a')); $p = PEG::seq('(', PEG::choice(PEG::ref($ref), PEG::anything()), ')'); $ref = $p; $c = PEG::context(array('(', 3, ')')); $t->is($p->parse($c), array('(', 3, ')')); $c = PEG::context(array('(', '(', 3, ')', ')')); $t->is($p->parse($c), array('(', array('(', 3, ')'), ')'));
<?php include_once dirname(__FILE__) . '/../code/PEG.php'; /** * 括弧の対応をとる再帰的なパーサのサンプル。 * 認識した括弧を用いて文字列を階層化する。 * * パーサのEBNFはこんな感じ * item := paren | anything * paren_item := (?! ")") item * paren := "(" paren_item* ")" * parser := item* */ $paren = PEG::ref($paren_ref); $item = PEG::choice($paren, PEG::anything()); $paren_item = PEG::andalso(PEG::not(')'), $item); $paren_ref = PEG::pack('(', PEG::many($paren_item), ')'); $parser = PEG::many($item); $str = 'abc(def(ghi)(jkl(mno)))pq'; var_dump($parser->parse(PEG::context($str))); /* 結果 array(6) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> string(1) "c" [3]=> array(5) { [0]=>
<?php include_once dirname(__FILE__) . '/t/t.php'; $t = new lime_test(); $choice = PEG::choice(PEG::token('hoge'), PEG::token('fuga')); $t->is($choice->parse(PEG::context('hoge')), 'hoge'); $t->is($choice->parse($c = PEG::context('fuga')), 'fuga'); $t->is($c->tell(), 4);
<?php include_once dirname(__FILE__) . '/../code/PEG.php'; /* * 単語にヒットするパーサ。 * * EBNF: * word := (PEG::alphabet | "_") (PEG::alphabet | PEG::digit | "_")+ */ $word = PEG::join(PEG::seq(PEG::choice(PEG::alphabet(), PEG::token('_')), PEG::many(PEG::choice(PEG::alphabet(), PEG::digit(), PEG::token('_'))))); var_dump($word->parse(PEG::context('a'))); //=> 'a' var_dump($word->parse(PEG::context('hogehoge'))); //=> 'hogehoge' var_dump($word->parse(PEG::context('some_id'))); //=> 'some_id' var_dump($word->parse(PEG::context(' '))); //=> パースに失敗する var_dump($word->parse(PEG::context('hoge fuga'))); //=> パースはコンテキストの途中で止まり 'hoge'が返る