finished default parser
This commit is contained in:
204
src/Domain/Modules/Interpreter/Builder.php
Normal file
204
src/Domain/Modules/Interpreter/Builder.php
Normal file
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
namespace XaiCorp\AbcParser\Domain\Modules\Interpreter;
|
||||
|
||||
use Enzyme\Axiom\Atoms\StringAtom;
|
||||
use XaiCorp\AbcParser\Domain\Atoms\EmailAtom;
|
||||
use XaiCorp\AbcParser\Domain\Atoms\UnsignedIntegerAtom;
|
||||
use XaiCorp\AbcParser\Domain\Core\Author;
|
||||
use XaiCorp\AbcParser\Domain\Core\Composer;
|
||||
use XaiCorp\AbcParser\Domain\Core\Setting;
|
||||
use XaiCorp\AbcParser\Domain\Core\Transcriber;
|
||||
use XaiCorp\AbcParser\Domain\Core\Tune;
|
||||
use XaiCorp\AbcParser\Domain\Core\TuneCollection;
|
||||
use XaiCorp\AbcParser\Models\Laravel5\TuneSetting;
|
||||
|
||||
class Builder
|
||||
{
|
||||
/**
|
||||
* @var Tune
|
||||
*/
|
||||
protected $tune;
|
||||
|
||||
/**
|
||||
* @var TuneCollection
|
||||
*/
|
||||
protected $collection;
|
||||
|
||||
/**
|
||||
* @var Setting
|
||||
*/
|
||||
protected $setting;
|
||||
|
||||
/**
|
||||
* Interpreter constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->collection = new TuneCollection();
|
||||
$this->tune = new Tune([]);
|
||||
$this->setting = new Setting();
|
||||
|
||||
$this->tune->addSetting($this->setting);
|
||||
}
|
||||
|
||||
public function getTune()
|
||||
{
|
||||
return $this->tune;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \XaiCorp\AbcParser\Domain\Core\TuneCollection
|
||||
*/
|
||||
public function getCollection()
|
||||
{
|
||||
return $this->collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function handleEndOfMusic()
|
||||
{
|
||||
if ($this->tune && empty($this->tune->getTitles())) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->tune->addSetting($this->setting);
|
||||
$this->collection[] = $this->tune;
|
||||
|
||||
$this->tune = new Tune([]);
|
||||
$this->setting = new Setting();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UnsignedIntegerAtom $index
|
||||
* @return $this
|
||||
*/
|
||||
public function setIndex(UnsignedIntegerAtom $index)
|
||||
{
|
||||
$this->tune->setIndex($index);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function appendMusic(StringAtom $musicLine)
|
||||
{
|
||||
$this->setting->addMusicLine($musicLine->getValue());
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addTitle(StringAtom $title)
|
||||
{
|
||||
$this->tune->addTitle($title->getValue());
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setKey(StringAtom $key)
|
||||
{
|
||||
$this->setting->setKey($key->getValue());
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setMeter(StringAtom $key)
|
||||
{
|
||||
$this->setting->setMeter($key->getValue());
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addAuthor(StringAtom $name)
|
||||
{
|
||||
$author = new Author($name, new EmailAtom(''));
|
||||
$this->tune->addAuthor($author);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addComposer(StringAtom $composerName)
|
||||
{
|
||||
$composer = new Composer($composerName, new EmailAtom(''));
|
||||
$this->tune->addComposer($composer);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addTranscriber(StringAtom $transcriberName)
|
||||
{
|
||||
$transcriber = new Transcriber($transcriberName, new EmailAtom(''));
|
||||
$this->setting->addTranscriber($transcriber);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addDiscography(StringAtom $recording)
|
||||
{
|
||||
$this->setting->addRecording($recording->getValue());
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addGroup(StringAtom $groupName)
|
||||
{
|
||||
$this->tune->addGroup($groupName->getValue());
|
||||
}
|
||||
|
||||
public function setParts(StringAtom $part)
|
||||
{
|
||||
$this->setting->setPart($part->getValue());
|
||||
}
|
||||
|
||||
public function addSource(StringAtom $source)
|
||||
{
|
||||
$this->setting->addSource($source->getValue());
|
||||
}
|
||||
|
||||
public function addFilename(StringAtom $filename)
|
||||
{
|
||||
$this->setting->addFilename($filename->getValue());
|
||||
}
|
||||
|
||||
public function addHistory(StringAtom $history)
|
||||
{
|
||||
$this->tune->addHistoryLine($history->getValue());
|
||||
}
|
||||
|
||||
public function addRhythm(StringAtom $rhythm)
|
||||
{
|
||||
$this->tune->addRhythm($rhythm->getValue());
|
||||
}
|
||||
|
||||
public function addBook(StringAtom $param)
|
||||
{
|
||||
$this->setting->addBook($param->getValue());
|
||||
}
|
||||
|
||||
public function addWords(StringAtom $param)
|
||||
{
|
||||
$this->setting->addWords($param->getValue());
|
||||
}
|
||||
|
||||
public function addTempo(StringAtom $param)
|
||||
{
|
||||
$this->setting->setTempo($param->getValue());
|
||||
}
|
||||
|
||||
public function addNoteLength(StringAtom $param)
|
||||
{
|
||||
$this->setting->setNoteLength($param->getValue());
|
||||
}
|
||||
|
||||
public function addNote(StringAtom $param)
|
||||
{
|
||||
$this->setting->addNote($param->getValue());
|
||||
}
|
||||
|
||||
public function addOrigin(StringAtom $param)
|
||||
{
|
||||
$this->tune->addOrigin($param->getValue());
|
||||
}
|
||||
}
|
||||
116
src/Domain/Modules/Interpreter/Context.php
Normal file
116
src/Domain/Modules/Interpreter/Context.php
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
namespace XaiCorp\AbcParser\Domain\Modules\Interpreter;
|
||||
|
||||
use Enzyme\Axiom\Atoms\StringAtom;
|
||||
use Enzyme\Collection\Collection;
|
||||
|
||||
class Context extends Collection
|
||||
{
|
||||
const MODE_NO_DATA = 0;
|
||||
const MODE_FILE_HEADER = 1;
|
||||
const MODE_TUNE_HEADER = 2;
|
||||
const MODE_TUNE_BODY = 3;
|
||||
const MODE_HISTORY = 4;
|
||||
|
||||
const ABC_VERSION_20 = '2.0';
|
||||
const ABC_VERSION_21 = '2.1';
|
||||
const ABC_VERSION_DEFAULT = self::ABC_VERSION_21;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
protected $abcText;
|
||||
|
||||
/**
|
||||
* @var Collection
|
||||
*/
|
||||
protected $abcLines;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $state = self::MODE_NO_DATA;
|
||||
|
||||
public function __construct(StringAtom $abc)
|
||||
{
|
||||
$this->abcText = $abc->getValue();
|
||||
|
||||
parent::__construct(preg_split("/(\r?\n)/", $abc->getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getState()
|
||||
{
|
||||
return $this->state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setStateInFileHeader()
|
||||
{
|
||||
$this->state = self::MODE_FILE_HEADER;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setStateInTuneHeader()
|
||||
{
|
||||
$this->state = self::MODE_TUNE_HEADER;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setStateInTuneBody()
|
||||
{
|
||||
$this->state = self::MODE_TUNE_BODY;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setStateInHistory()
|
||||
{
|
||||
$this->state = self::MODE_HISTORY;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setStateInBetween()
|
||||
{
|
||||
$this->state = self::MODE_NO_DATA;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $state
|
||||
* @return bool
|
||||
*/
|
||||
public function isState(int $state) : bool
|
||||
{
|
||||
return $this->state === $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* get abc version of the file
|
||||
* @return string
|
||||
*/
|
||||
public function getVersion()
|
||||
{
|
||||
return '2.1';
|
||||
}
|
||||
}
|
||||
121
src/Domain/Modules/Interpreter/DefaultInterpreter.php
Normal file
121
src/Domain/Modules/Interpreter/DefaultInterpreter.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
namespace XaiCorp\AbcParser\Domain\Modules\Interpreter;
|
||||
|
||||
use Enzyme\Axiom\Atoms\StringAtom;
|
||||
use XaiCorp\AbcParser\Domain\Core\Tune;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon\Author;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon\Book;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon\Composer;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon\Discography;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon\EndOfTune;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon\Filename;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon\Group;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon\History;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon\Index;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon\KeySignature;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon\Meter;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon\MusicLine;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon\NoteLength;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon\Notes;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon\Origin;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon\Parts;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon\Rhythm;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon\Source;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon\Tempo;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon\Title;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon\Transcriber;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon\Words;
|
||||
|
||||
class DefaultInterpreter extends Interpreter
|
||||
{
|
||||
protected $keyMap = [
|
||||
'K' => 'key',
|
||||
'L' => 'length',
|
||||
'M' => 'meter',
|
||||
'P' => 'part',
|
||||
'Q' => 'tempo',
|
||||
'B' => 'book',
|
||||
'N' => 'note',
|
||||
'D' => 'disc',
|
||||
'S' => 'source',
|
||||
'W' => 'words',
|
||||
'Z' => 'transcriber',
|
||||
'F' => 'filename',
|
||||
'H' => 'history',
|
||||
'A' => 'author',
|
||||
'C' => 'composer',
|
||||
'G' => 'group',
|
||||
'R' => 'rhythm',
|
||||
'T' => 'title',
|
||||
'O' => 'origin'
|
||||
];
|
||||
|
||||
protected $lexers = [
|
||||
Index::class,
|
||||
Title::class,
|
||||
Author::class,
|
||||
Book::class,
|
||||
Composer::class,
|
||||
Transcriber::class,
|
||||
Discography::class,
|
||||
Group::class,
|
||||
Source::class,
|
||||
Origin::class,
|
||||
KeySignature::class,
|
||||
Meter::class,
|
||||
Parts::class,
|
||||
Tempo::class,
|
||||
NoteLength::class,
|
||||
Notes::class,
|
||||
History::class,
|
||||
Filename::class,
|
||||
Words::class,
|
||||
Rhythm::class,
|
||||
MusicLine::class,
|
||||
EndOfTune::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @param \XaiCorp\AbcParser\Domain\Modules\Interpreter\Context $context
|
||||
* @return $this
|
||||
*/
|
||||
public function execute(Context $context)
|
||||
{
|
||||
$lexicon = $this->pipeline();
|
||||
|
||||
do {
|
||||
$result = (new InterpreterPipeline())
|
||||
->send($context)
|
||||
->through($lexicon)
|
||||
->via('handle')
|
||||
->then(function ($context) {
|
||||
return $context;
|
||||
});
|
||||
$context->next();
|
||||
} while ($context->count() > $context->key());
|
||||
|
||||
// return $this->builder->getTune();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getLastTune()
|
||||
{
|
||||
return $this->builder->getTune();
|
||||
}
|
||||
|
||||
public function getTunes()
|
||||
{
|
||||
return $this->builder->getCollection();
|
||||
}
|
||||
|
||||
protected function pipeline()
|
||||
{
|
||||
$pipeline = [];
|
||||
|
||||
foreach ($this->lexers as $lexerClass) {
|
||||
$pipeline[] = new $lexerClass($this->builder);
|
||||
}
|
||||
|
||||
return $pipeline;
|
||||
}
|
||||
}
|
||||
36
src/Domain/Modules/Interpreter/Interpreter.php
Normal file
36
src/Domain/Modules/Interpreter/Interpreter.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
namespace XaiCorp\AbcParser\Domain\Modules\Interpreter;
|
||||
|
||||
use XaiCorp\AbcParser\Domain\Core\Tune;
|
||||
use XaiCorp\AbcParser\Domain\Core\TuneCollection;
|
||||
|
||||
abstract class Interpreter
|
||||
{
|
||||
const LN_VERSION = '/^%abc(-\d\.\d)?$/';
|
||||
const LN_BLANK = '/^\s*$/';
|
||||
const LN_FIELD = '/^\w:(.+)$/';
|
||||
|
||||
/**
|
||||
* @var Builder
|
||||
*/
|
||||
protected $builder;
|
||||
|
||||
/**
|
||||
* Interpreter constructor.
|
||||
*/
|
||||
public function __construct(Builder $builder)
|
||||
{
|
||||
$this->builder = $builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Context $context
|
||||
* @return Interpreter
|
||||
*/
|
||||
abstract public function execute(Context $context);
|
||||
|
||||
/**
|
||||
* @return TuneCollection
|
||||
*/
|
||||
abstract public function getTunes();
|
||||
}
|
||||
9
src/Domain/Modules/Interpreter/InterpreterPipeline.php
Normal file
9
src/Domain/Modules/Interpreter/InterpreterPipeline.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
namespace XaiCorp\AbcParser\Domain\Modules\Interpreter;
|
||||
|
||||
use Illuminate\Pipeline\Pipeline;
|
||||
|
||||
class InterpreterPipeline extends Pipeline
|
||||
{
|
||||
|
||||
}
|
||||
40
src/Domain/Modules/Interpreter/Lexicon/Composer.php
Normal file
40
src/Domain/Modules/Interpreter/Lexicon/Composer.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
namespace XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon;
|
||||
|
||||
use Enzyme\Axiom\Atoms\StringAtom;
|
||||
use XaiCorp\AbcParser\Domain\Atoms\UnsignedIntegerAtom;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Builder;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Context;
|
||||
|
||||
class Composer implements Lex
|
||||
{
|
||||
use LineKeyDataTrait;
|
||||
|
||||
/**
|
||||
* @var Builder
|
||||
*/
|
||||
protected $builder;
|
||||
|
||||
public function __construct(Builder $builder)
|
||||
{
|
||||
$this->builder = $builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Context $context
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
* @throws \Enzyme\Axiom\Exceptions\AtomException
|
||||
*/
|
||||
public function handle(Context $context, \Closure $next)
|
||||
{
|
||||
$line = $context->current();
|
||||
list($key, $data) = $this->getKeyDataFromLine($line);
|
||||
|
||||
if ($key === 'C') {
|
||||
$this->builder->addComposer(new StringAtom($data));
|
||||
}
|
||||
|
||||
return $next($context);
|
||||
}
|
||||
}
|
||||
36
src/Domain/Modules/Interpreter/Lexicon/Index.php
Normal file
36
src/Domain/Modules/Interpreter/Lexicon/Index.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
namespace XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon;
|
||||
|
||||
use Enzyme\Axiom\Atoms\StringAtom;
|
||||
use XaiCorp\AbcParser\Domain\Atoms\UnsignedIntegerAtom;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Builder;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Context;
|
||||
|
||||
class Index implements Lex
|
||||
{
|
||||
use LineKeyDataTrait;
|
||||
|
||||
/**
|
||||
* @var Builder
|
||||
*/
|
||||
protected $builder;
|
||||
|
||||
public function __construct(Builder $builder)
|
||||
{
|
||||
$this->builder = $builder;
|
||||
}
|
||||
|
||||
public function handle(Context $context, \Closure $next)
|
||||
{
|
||||
$line = $context->current();
|
||||
list($key, $data) = $this->getKeyDataFromLine($line);
|
||||
|
||||
if ($key === 'X') {
|
||||
$context->setStateInTuneHeader();
|
||||
|
||||
$this->builder->setIndex(new UnsignedIntegerAtom($data));
|
||||
}
|
||||
|
||||
return $next($context);
|
||||
}
|
||||
}
|
||||
7
src/Domain/Modules/Interpreter/Lexicon/Lex.php
Normal file
7
src/Domain/Modules/Interpreter/Lexicon/Lex.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
namespace XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon;
|
||||
|
||||
interface Lex
|
||||
{
|
||||
|
||||
}
|
||||
23
src/Domain/Modules/Interpreter/Lexicon/LineKeyDataTrait.php
Normal file
23
src/Domain/Modules/Interpreter/Lexicon/LineKeyDataTrait.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
namespace XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon;
|
||||
|
||||
trait LineKeyDataTrait
|
||||
{
|
||||
/**
|
||||
* @param string $line
|
||||
* @return array [$key, $data]
|
||||
*/
|
||||
protected function getKeyDataFromLine(string $line)
|
||||
{
|
||||
$key = '';
|
||||
$data = '';
|
||||
$matches = [];
|
||||
preg_match('/^(.):(.*)/', $line, $matches);
|
||||
|
||||
if (count($matches) === 3) {
|
||||
$key = trim($matches[1]);
|
||||
$data = trim($matches[2]);
|
||||
}
|
||||
return [$key, $data];
|
||||
}
|
||||
}
|
||||
40
src/Domain/Modules/Interpreter/Lexicon/Title.php
Normal file
40
src/Domain/Modules/Interpreter/Lexicon/Title.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
namespace XaiCorp\AbcParser\Domain\Modules\Interpreter\Lexicon;
|
||||
|
||||
use Enzyme\Axiom\Atoms\StringAtom;
|
||||
use XaiCorp\AbcParser\Domain\Atoms\UnsignedIntegerAtom;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Builder;
|
||||
use XaiCorp\AbcParser\Domain\Modules\Interpreter\Context;
|
||||
|
||||
class Title implements Lex
|
||||
{
|
||||
use LineKeyDataTrait;
|
||||
|
||||
/**
|
||||
* @var Builder
|
||||
*/
|
||||
protected $builder;
|
||||
|
||||
public function __construct(Builder $builder)
|
||||
{
|
||||
$this->builder = $builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Context $context
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
* @throws \Enzyme\Axiom\Exceptions\AtomException
|
||||
*/
|
||||
public function handle(Context $context, \Closure $next)
|
||||
{
|
||||
$line = $context->current();
|
||||
list($key, $data) = $this->getKeyDataFromLine($line);
|
||||
|
||||
if ($key === 'T') {
|
||||
$this->builder->addTitle(new StringAtom($data));
|
||||
}
|
||||
|
||||
return $next($context);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user