Browse Source

Move to PSR-1 and PSR-2.

tags/2.15.05.29
Ivan Enderlin 5 years ago
parent
commit
5b971e8745
34 changed files with 1533 additions and 1642 deletions
  1. +81
    -81
      Bin/Pp.php
  2. +59
    -43
      Documentation/En/Index.xyl
  3. +59
    -43
      Documentation/Fr/Index.xyl
  4. +5
    -5
      Exception/Exception.php
  5. +5
    -5
      Exception/FinalStateHasNotBeenReached.php
  6. +9
    -13
      Exception/IllegalToken.php
  7. +5
    -5
      Exception/Lexer.php
  8. +5
    -6
      Exception/Rule.php
  9. +5
    -5
      Exception/UnexpectedToken.php
  10. +9
    -13
      Exception/UnrecognizedToken.php
  11. +202
    -227
      Ll1.php
  12. +72
    -57
      Llk/Lexer.php
  13. +59
    -62
      Llk/Llk.php
  14. +190
    -207
      Llk/Parser.php
  15. +135
    -120
      Llk/Rule/Analyzer.php
  16. +5
    -6
      Llk/Rule/Choice.php
  17. +5
    -6
      Llk/Rule/Concatenation.php
  18. +5
    -6
      Llk/Rule/Ekzit.php
  19. +5
    -6
      Llk/Rule/Entry.php
  20. +27
    -34
      Llk/Rule/Invocation.php
  21. +12
    -18
      Llk/Rule/Repetition.php
  22. +44
    -67
      Llk/Rule/Rule.php
  23. +39
    -54
      Llk/Rule/Token.php
  24. +79
    -93
      Llk/Sampler/BoundedExhaustive.php
  25. +178
    -197
      Llk/Sampler/Coverage.php
  26. +5
    -5
      Llk/Sampler/Exception.php
  27. +31
    -39
      Llk/Sampler/Sampler.php
  28. +82
    -86
      Llk/Sampler/Uniform.php
  29. +58
    -76
      Llk/TreeNode.php
  30. +2
    -1
      README.md
  31. +7
    -9
      Test/Unit/Documentation.php
  32. +14
    -16
      Test/Unit/Llk/Llk.php
  33. +5
    -5
      Test/Unit/Llk/Soundness.php
  34. +30
    -26
      Visitor/Dump.php

+ 81
- 81
Bin/Pp.php View File

@@ -8,7 +8,7 @@
*
* New BSD License
*
* Copyright © 2007-2015, Ivan Enderlin. All rights reserved.
* Copyright © 2007-2015, Hoa community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -45,17 +45,15 @@ use Hoa\File;
*
* Play with PP.
*
* @author Ivan Enderlin <ivan.enderlin@hoa-project.net>
* @copyright Copyright © 2007-2015 Ivan Enderlin.
* @copyright Copyright © 2007-2015 Hoa community
* @license New BSD License
*/

class Pp extends Console\Dispatcher\Kit {

class Pp extends Console\Dispatcher\Kit
{
/**
* Options description.
*
* @var \Hoa\Compiler\Bin\Pp array
* @var array
*/
protected $options = [
['visitor', Console\GetOption::REQUIRED_ARGUMENT, 'v'],
@@ -71,68 +69,69 @@ class Pp extends Console\Dispatcher\Kit {
/**
* The entry method.
*
* @access public
* @return int
*/
public function main ( ) {
public function main()
{
$visitor = null;
$tokenSequence = false;
$trace = false;

while(false !== $c = $this->getOption($v)) switch($c) {
while (false !== $c = $this->getOption($v)) {
switch ($c) {
case 'v':
switch (strtolower($v)) {
case 'dump':
$visitor = 'Hoa\Compiler\Visitor\Dump';

case 'v':
switch(strtolower($v)) {
break;

case 'dump':
$visitor = 'Hoa\Compiler\Visitor\Dump';
break;
default:
return $this->usage();
}

default:
return $this->usage();
}
break;
break;

case 'c':
$visitor = str_replace('.', '\\', $v);

break;

case 's':
$tokenSequence = true;

case 'c':
$visitor = str_replace('.', '\\', $v);
break;
break;

case 's':
$tokenSequence = true;
break;
case 't':
$trace = true;

case 't':
$trace = true;
break;
break;

case '__ambiguous':
$this->resolveOptionAmbiguity($v);
break;
case '__ambiguous':
$this->resolveOptionAmbiguity($v);

case 'h':
case '?':
default:
return $this->usage();
break;
break;

case 'h':
case '?':
default:
return $this->usage();
}
}

$this->parser->listInputs($grammar, $language);

if(empty($grammar) || (empty($language) && '0' !== $language))
if (empty($grammar) || (empty($language) && '0' !== $language)) {
return $this->usage();
}

$compiler = Compiler\Llk::load(new File\Read($grammar));
$data = new File\Read($language);

try {

$ast = $compiler->parse($data->readAll());
}
catch ( Compiler\Exception $e ) {

if(true === $tokenSequence) {

} catch (Compiler\Exception $e) {
if (true === $tokenSequence) {
$this->printTokenSequence($compiler);
echo "\n\n";
}
@@ -142,20 +141,17 @@ class Pp extends Console\Dispatcher\Kit {
return 1;
}

if(true === $tokenSequence) {

if (true === $tokenSequence) {
$this->printTokenSequence($compiler);
echo "\n\n";
}

if(true === $trace) {

if (true === $trace) {
$this->printTrace($compiler);
echo "\n\n";
}

if(null !== $visitor) {

if (null !== $visitor) {
$visitor = dnew($visitor);
echo $visitor->visit($ast);
}
@@ -166,32 +162,36 @@ class Pp extends Console\Dispatcher\Kit {
/**
* Print trace.
*
* @access protected
* @param \Hoa\Compiler\Llk\Parser $compiler Compiler.
* @return void
*/
protected function printTrace ( Compiler\Llk\Parser $compiler ) {
protected function printTrace(Compiler\Llk\Parser $compiler)
{
$i = 0;

foreach($compiler->getTrace() as $element)
if($element instanceof Compiler\Llk\Rule\Entry) {

foreach ($compiler->getTrace() as $element) {
if ($element instanceof Compiler\Llk\Rule\Entry) {
$ruleName = $element->getRule();
$rule = $compiler->getRule($ruleName);

echo str_repeat('> ', ++$i), 'enter ', $ruleName;

if(null !== $id = $rule->getNodeId())
if (null !== $id = $rule->getNodeId()) {
echo ' (', $id, ')';
}

echo "\n";
}
elseif($element instanceof Compiler\Llk\Rule\Token)
echo str_repeat(' ', $i + 1), 'token ',$element->getTokenName(),
} elseif ($element instanceof Compiler\Llk\Rule\Token) {
echo
str_repeat(' ', $i + 1),
'token ', $element->getTokenName(),
', consumed ', $element->getValue(), "\n";
else
echo str_repeat('< ', $i--), 'ekzit ', $element->getRule(), "\n";
} else {
echo
str_repeat('< ', $i--),
'ekzit ', $element->getRule(), "\n";
}
}

return;
}
@@ -199,12 +199,11 @@ class Pp extends Console\Dispatcher\Kit {
/**
* Print token sequence.
*
* @access protected
* @param \Hoa\Compiler\Llk\Parser $compiler Compiler.
* @return void
*/
protected function printTokenSequence ( Compiler\Llk\Parser $compiler ) {
protected function printTokenSequence(Compiler\Llk\Parser $compiler)
{
$sequence = $compiler->getTokenSequence();
$format = '%' . (strlen((string) count($sequence)) + 1) . 's ' .
'%-13s %-20s %s %6s' . "\n";
@@ -220,7 +219,7 @@ class Pp extends Console\Dispatcher\Kit {

echo $header, str_repeat('-', strlen($header)), "\n";

foreach($sequence as $i => $token)
foreach ($sequence as $i => $token) {
printf(
$format,
$i,
@@ -229,11 +228,12 @@ class Pp extends Console\Dispatcher\Kit {
30 < $token['length']
? mb_substr($token['value'], 0, 29) . '…'
: 'EOF' === $token['token']
? str_repeat(' ', 30)
: $token['value'] .
str_repeat(' ', 30 - $token['length']),
? str_repeat(' ', 30)
: $token['value'] .
str_repeat(' ', 30 - $token['length']),
$token['offset']
);
}

return;
}
@@ -241,20 +241,20 @@ class Pp extends Console\Dispatcher\Kit {
/**
* The command usage.
*
* @access public
* @return int
*/
public function usage ( ) {

echo 'Usage : compiler:pp <options> [grammar.pp] [language]', "\n",
'Options :', "\n",
$this->makeUsageOptionsList([
'v' => 'Visitor name (only “dump” is supported).',
'c' => 'Visitor classname (using . instead of \ works).',
's' => 'Print token sequence.',
't' => 'Print trace.',
'help' => 'This help.'
]), "\n";
public function usage()
{
echo
'Usage : compiler:pp <options> [grammar.pp] [language]', "\n",
'Options :', "\n",
$this->makeUsageOptionsList([
'v' => 'Visitor name (only “dump” is supported).',
'c' => 'Visitor classname (using . instead of \ works).',
's' => 'Print token sequence.',
't' => 'Print trace.',
'help' => 'This help.'
]), "\n";

return;
}


+ 59
- 43
Documentation/En/Index.xyl View File

@@ -487,7 +487,7 @@ $header = sprintf($format, '#', 'namespace', 'token name', 'token value', 'off

echo $header, str_repeat('-', strlen($header)), "\n";

foreach($sequence as $i => $token)
foreach ($sequence as $i => $token) {
printf(
$format,
$i,
@@ -496,6 +496,7 @@ foreach($sequence as $i => $token)
$token['value'],
$token['offset']
);
}

/**
* Will output:
@@ -662,66 +663,71 @@ rule:
one method to implement: <code>visit</code> with three arguments:
the element and two optional arguments (by reference and by copy). Let's
see:</p>
<pre><code class="language-php">class PrettyPrinter implements Hoa\Visitor\Visit {

public function visit ( Hoa\Visitor\Element $element,
&amp;amp;$handle = null, $eldnah = null ) {

<pre><code class="language-php">class PrettyPrinter implements Hoa\Visitor\Visit
{
public function visit (
Hoa\Visitor\Element $element,
&amp;amp;$handle = null,
$eldnah = null
) {
static $i = 0;
static $indent = ' ';

// One behaviour per node in the AST.
switch($element->getId()) {

switch ($element->getId()) {
// Object: { … }.
case '#object':
echo '{', "\n";
++$i;

foreach($element->getChildren() as $e => $child) {

if(0 &amp;lt; $e)
foreach ($element->getChildren() as $e => $child) {
if (0 &amp;lt; $e) {
echo ',', "\n";
}

echo str_repeat($indent, $i);
$child->accept($this, $handle, $eldnah);
}

echo "\n", str_repeat($indent, --$i), '}';
break;

break;

// Array: [ … ].
case '#array':
echo '[', "\n";
++$i;

foreach($element->getChildren() as $e => $child) {

if(0 &amp;lt; $e)
foreach ($element->getChildren() as $e => $child) {
if (0 &amp;lt; $e) {
echo ',', "\n";
}

echo str_repeat($indent, $i);
$child->accept($this, $handle, $eldnah);
}

echo "\n", str_repeat($indent, --$i), ']';
break;

break;

// Pair: "…": ….
case '#pair':
echo $element->getChild(0)->accept($this, $handle, $eldnah),
': ',
$element->getChild(1)->accept($this, $handle, $eldnah);
break;
echo
$element->getChild(0)->accept($this, $handle, $eldnah),
': ',
$element->getChild(1)->accept($this, $handle, $eldnah);

break;

// Many tokens.
case 'token':
switch($element->getValueToken()) {

switch ($element->getValueToken()) {
// String: "…".
case 'string':
echo '"', $element->getValueValue(), '"';
break;

break;

// Booleans.
case 'true':
@@ -733,9 +739,11 @@ rule:
// Number.
case 'number':
echo $element->getValueValue();
break;

break;
}
break;

break;
}
}
}</code></pre>
@@ -761,8 +769,9 @@ echo $prettyPrint->visit($ast);
array; thus:</p>
<pre><code class="language-php">$data = $element->getData();

if(!isset($data['previousComputing']))
if (!isset($data['previousComputing'])) {
throw new Exception('Need a previous computing.', 0);
}

$previous = $data['previousComputing'];</code></pre>
<p>It is common to use one visitor per <strong>constraint</strong>:
@@ -815,14 +824,17 @@ $previous = $data['previousComputing'];</code></pre>
$ast = $compiler->parse('{"foo": true, "bar": [null, 42]}');
$i = 0;

foreach($compiler->getTrace() as $element)
if($element instanceof Hoa\Compiler\Llk\Rule\Entry)
foreach ($compiler->getTrace() as $element) {
if ($element instanceof Hoa\Compiler\Llk\Rule\Entry) {
echo str_repeat('> ', ++$i), 'enter ', $element->getRule(), "\n";
elseif($element instanceof Hoa\Compiler\Llk\Rule\Token)
echo str_repeat(' ', $i + 1), 'token ', $element->getTokenName(),
', consumed ', $element->getValue(), "\n";
else
} elseif ($element instanceof Hoa\Compiler\Llk\Rule\Token) {
echo
str_repeat(' ', $i + 1), 'token ', $element->getTokenName(),
', consumed ', $element->getValue(), "\n";
} else {
echo str_repeat('&amp;lt; ', $i--), 'ekzit ', $element->getRule(), "\n";
}
}

/**
* Will output:
@@ -912,27 +924,28 @@ $rules = $compiler->getRules();
// 2. Start with the root rule.
$stack = [$compiler->getRootRule() => true];

while(false !== current($stack)) {

while (false !== current($stack)) {
$rule = key($stack);
next($stack);
echo "\n", '"', $rule, '" is a ',
strtolower(substr(get_class($rules[$rule]), 22));
echo
"\n", '"', $rule, '" is a ',
strtolower(substr(get_class($rules[$rule]), 22));

$subrules = $rules[$rule]->getContent();

// 3a. Token.
if(null === $subrules)
if (null === $subrules) {
continue;
}

echo ' of rules: ';

// 3b. Other rules.
foreach((array) $rules[$rule]->getContent() as $subrule) {

if(!array_key_exists($subrule, $stack))
foreach ((array) $rules[$rule]->getContent() as $subrule) {
if (!array_key_exists($subrule, $stack)) {
// 4. Unshift new rules to print.
$stack[$subrule] = true;
}

echo $subrule, ' ';
}
@@ -1058,8 +1071,9 @@ while(false !== current($stack)) {
7
);

for($i = 0; $i &amp;lt; 10; ++$i)
for ($i = 0; $i &amp;lt; 10; ++$i) {
echo $i, ' => ', $sampler->uniform(), "\n";
}

/**
* Will output:
@@ -1097,8 +1111,9 @@ for($i = 0; $i &amp;lt; 10; ++$i)
7
);

foreach($sampler as $i => $data)
foreach ($sampler as $i => $data) {
echo $i, ' => ', $data, "\n";
}

/**
* Will output:
@@ -1151,8 +1166,9 @@ foreach($sampler as $i => $data)
new Hoa\Regex\Visitor\Isotropic(new Hoa\Math\Sampler\Random())
);

foreach($sampler as $i => $data)
foreach ($sampler as $i => $data) {
echo $i, ' => ', $data, "\n";
}

/**
* Will output:


+ 59
- 43
Documentation/Fr/Index.xyl View File

@@ -511,7 +511,7 @@ $header = sprintf($format, '#', 'namespace', 'token name', 'token value', 'off

echo $header, str_repeat('-', strlen($header)), "\n";

foreach($sequence as $i => $token)
foreach ($sequence as $i => $token) {
printf(
$format,
$i,
@@ -520,6 +520,7 @@ foreach($sequence as $i => $token)
$token['value'],
$token['offset']
);
}

/**
* Will output:
@@ -695,66 +696,71 @@ rule:
méthode à écrire : <code>visit</code> qui prend trois arguments :
l'élément et deux arguments accessoires (en référence et en copie). Voyons
plutôt :</p>
<pre><code class="language-php">class PrettyPrinter implements Hoa\Visitor\Visit {

public function visit ( Hoa\Visitor\Element $element,
&amp;amp;$handle = null, $eldnah = null ) {

<pre><code class="language-php">class PrettyPrinter implements Hoa\Visitor\Visit
{
public function visit (
Hoa\Visitor\Element $element,
&amp;amp;$handle = null,
$eldnah = null
) {
static $i = 0;
static $indent = ' ';

// One behaviour per node in the AST.
switch($element->getId()) {

switch ($element->getId()) {
// Object: { … }.
case '#object':
echo '{', "\n";
++$i;

foreach($element->getChildren() as $e => $child) {

if(0 &amp;lt; $e)
foreach ($element->getChildren() as $e => $child) {
if (0 &amp;lt; $e) {
echo ',', "\n";
}

echo str_repeat($indent, $i);
$child->accept($this, $handle, $eldnah);
}

echo "\n", str_repeat($indent, --$i), '}';
break;

break;

// Array: [ … ].
case '#array':
echo '[', "\n";
++$i;

foreach($element->getChildren() as $e => $child) {

if(0 &amp;lt; $e)
foreach ($element->getChildren() as $e => $child) {
if (0 &amp;lt; $e) {
echo ',', "\n";
}

echo str_repeat($indent, $i);
$child->accept($this, $handle, $eldnah);
}

echo "\n", str_repeat($indent, --$i), ']';
break;

break;

// Pair: "…": ….
case '#pair':
echo $element->getChild(0)->accept($this, $handle, $eldnah),
': ',
$element->getChild(1)->accept($this, $handle, $eldnah);
break;
echo
$element->getChild(0)->accept($this, $handle, $eldnah),
': ',
$element->getChild(1)->accept($this, $handle, $eldnah);

break;

// Many tokens.
case 'token':
switch($element->getValueToken()) {

switch ($element->getValueToken()) {
// String: "…".
case 'string':
echo '"', $element->getValueValue(), '"';
break;

break;

// Booleans.
case 'true':
@@ -766,9 +772,11 @@ rule:
// Number.
case 'number':
echo $element->getValueValue();
break;

break;
}
break;

break;
}
}
}</code></pre>
@@ -794,8 +802,9 @@ echo $prettyPrint->visit($ast);
méthode retourne une <strong>référence</strong> sur un tableau ; ainsi :</p>
<pre><code class="language-php">$data = $element->getData();

if(!isset($data['previousComputing']))
if (!isset($data['previousComputing'])) {
throw new Exception('Need a previous computing.', 0);
}

$previous = $data['previousComputing'];</code></pre>
<p>Il est courant d'utiliser un visiteur par <strong>contrainte</strong> :
@@ -848,14 +857,17 @@ $previous = $data['previousComputing'];</code></pre>
$ast = $compiler->parse('{"foo": true, "bar": [null, 42]}');
$i = 0;

foreach($compiler->getTrace() as $element)
if($element instanceof Hoa\Compiler\Llk\Rule\Entry)
foreach ($compiler->getTrace() as $element) {
if ($element instanceof Hoa\Compiler\Llk\Rule\Entry) {
echo str_repeat('> ', ++$i), 'enter ', $element->getRule(), "\n";
elseif($element instanceof Hoa\Compiler\Llk\Rule\Token)
echo str_repeat(' ', $i + 1), 'token ', $element->getTokenName(),
', consumed ', $element->getValue(), "\n";
else
} elseif ($element instanceof Hoa\Compiler\Llk\Rule\Token) {
echo
str_repeat(' ', $i + 1), 'token ', $element->getTokenName(),
', consumed ', $element->getValue(), "\n";
} else {
echo str_repeat('&amp;lt; ', $i--), 'ekzit ', $element->getRule(), "\n";
}
}

/**
* Will output:
@@ -946,27 +958,28 @@ $rules = $compiler->getRules();
// 2. Start with the root rule.
$stack = [$compiler->getRootRule() => true];

while(false !== current($stack)) {

while (false !== current($stack)) {
$rule = key($stack);
next($stack);
echo "\n", '"', $rule, '" is a ',
strtolower(substr(get_class($rules[$rule]), 22));
echo
"\n", '"', $rule, '" is a ',
strtolower(substr(get_class($rules[$rule]), 22));

$subrules = $rules[$rule]->getContent();

// 3a. Token.
if(null === $subrules)
if (null === $subrules) {
continue;
}

echo ' of rules: ';

// 3b. Other rules.
foreach((array) $rules[$rule]->getContent() as $subrule) {

if(!array_key_exists($subrule, $stack))
foreach ((array) $rules[$rule]->getContent() as $subrule) {
if (!array_key_exists($subrule, $stack)) {
// 4. Unshift new rules to print.
$stack[$subrule] = true;
}

echo $subrule, ' ';
}
@@ -1098,8 +1111,9 @@ while(false !== current($stack)) {
7
);

for($i = 0; $i &amp;lt; 10; ++$i)
for ($i = 0; $i &amp;lt; 10; ++$i) {
echo $i, ' => ', $sampler->uniform(), "\n";
}

/**
* Will output:
@@ -1138,8 +1152,9 @@ for($i = 0; $i &amp;lt; 10; ++$i)
7
);

foreach($sampler as $i => $data)
foreach ($sampler as $i => $data) {
echo $i, ' => ', $data, "\n";
}

/**
* Will output:
@@ -1195,8 +1210,9 @@ foreach($sampler as $i => $data)
new Hoa\Regex\Visitor\Isotropic(new Hoa\Math\Sampler\Random())
);

foreach($sampler as $i => $data)
foreach ($sampler as $i => $data) {
echo $i, ' => ', $data, "\n";
}

/**
* Will output:


+ 5
- 5
Exception/Exception.php View File

@@ -8,7 +8,7 @@
*
* New BSD License
*
* Copyright © 2007-2015, Ivan Enderlin. All rights reserved.
* Copyright © 2007-2015, Hoa community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -43,12 +43,12 @@ use Hoa\Core;
*
* Extending the \Hoa\Core\Exception class.
*
* @author Ivan Enderlin <ivan.enderlin@hoa-project.net>
* @copyright Copyright © 2007-2015 Ivan Enderlin.
* @copyright Copyright © 2007-2015 Hoa community
* @license New BSD License
*/

class Exception extends Core\Exception { }
class Exception extends Core\Exception
{
}

/**
* Flex entity.


+ 5
- 5
Exception/FinalStateHasNotBeenReached.php View File

@@ -8,7 +8,7 @@
*
* New BSD License
*
* Copyright © 2007-2015, Ivan Enderlin. All rights reserved.
* Copyright © 2007-2015, Hoa community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -41,9 +41,9 @@ namespace Hoa\Compiler\Exception;
*
* Extending the \Hoa\Compiler\Exception class.
*
* @author Ivan Enderlin <ivan.enderlin@hoa-project.net>
* @copyright Copyright © 2007-2015 Ivan Enderlin.
* @copyright Copyright © 2007-2015 Hoa community
* @license New BSD License
*/

class FinalStateHasNotBeenReached extends Exception { }
class FinalStateHasNotBeenReached extends Exception
{
}

+ 9
- 13
Exception/IllegalToken.php View File

@@ -8,7 +8,7 @@
*
* New BSD License
*
* Copyright © 2007-2015, Ivan Enderlin. All rights reserved.
* Copyright © 2007-2015, Hoa community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -41,17 +41,15 @@ namespace Hoa\Compiler\Exception;
*
* Extending the \Hoa\Compiler\Exception class.
*
* @author Ivan Enderlin <ivan.enderlin@hoa-project.net>
* @copyright Copyright © 2007-2015 Ivan Enderlin.
* @copyright Copyright © 2007-2015 Hoa community
* @license New BSD License
*/

class IllegalToken extends Exception {

class IllegalToken extends Exception
{
/**
* Column.
*
* @var \Hoa\Compiler\Exception\IllegalToken int
* @var int
*/
protected $column = 0;

@@ -60,7 +58,6 @@ class IllegalToken extends Exception {
/**
* Override line and add column support.
*
* @access public
* @param string $message Formatted message.
* @param int $code Code (the ID).
* @param array $arg RaiseError string arguments.
@@ -68,8 +65,8 @@ class IllegalToken extends Exception {
* @param int $column Column.
* @return void
*/
public function __construct ( $message, $code, $arg, $line, $column ) {
public function __construct($message, $code, $arg, $line, $column)
{
parent::__construct($message, $code, $arg);

$this->line = $line;
@@ -81,11 +78,10 @@ class IllegalToken extends Exception {
/**
* Get column.
*
* @access public
* @return int
*/
public function getColumn ( ) {
public function getColumn()
{
return $this->column;
}
}

+ 5
- 5
Exception/Lexer.php View File

@@ -8,7 +8,7 @@
*
* New BSD License
*
* Copyright © 2007-2015, Ivan Enderlin. All rights reserved.
* Copyright © 2007-2015, Hoa community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -41,9 +41,9 @@ namespace Hoa\Compiler\Exception;
*
* Extending the \Hoa\Compiler\Exception class.
*
* @author Ivan Enderlin <ivan.enderlin@hoa-project.net>
* @copyright Copyright © 2007-2015 Ivan Enderlin.
* @copyright Copyright © 2007-2015 Hoa community
* @license New BSD License
*/

class Lexer extends Exception { }
class Lexer extends Exception
{
}

+ 5
- 6
Exception/Rule.php View File

@@ -8,7 +8,7 @@
*
* New BSD License
*
* Copyright © 2007-2015, Ivan Enderlin. All rights reserved.
* Copyright © 2007-2015, Hoa community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -41,10 +41,9 @@ namespace Hoa\Compiler\Exception;
*
* Extending the \Hoa\Compiler\Exception class.
*
* @author Frédéric Dadeau <frederic.dadeau@femto-st.fr>
* @author Ivan Enderlin <ivan.enderlin@hoa-project.net>
* @copyright Copyright © 2007-2015 Frédéric Dadeau, Ivan Enderlin.
* @copyright Copyright © 2007-2015 Hoa community
* @license New BSD License
*/

class Rule extends Exception { }
class Rule extends Exception
{
}

+ 5
- 5
Exception/UnexpectedToken.php View File

@@ -8,7 +8,7 @@
*
* New BSD License
*
* Copyright © 2007-2015, Ivan Enderlin. All rights reserved.
* Copyright © 2007-2015, Hoa community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -41,9 +41,9 @@ namespace Hoa\Compiler\Exception;
*
* Extending the \Hoa\Compiler\Exception\UnrecognizedToken class.
*
* @author Ivan Enderlin <ivan.enderlin@hoa-project.net>
* @copyright Copyright © 2007-2015 Ivan Enderlin.
* @copyright Copyright © 2007-2015 Hoa community
* @license New BSD License
*/

class UnexpectedToken extends UnrecognizedToken { }
class UnexpectedToken extends UnrecognizedToken
{
}

+ 9
- 13
Exception/UnrecognizedToken.php View File

@@ -8,7 +8,7 @@
*
* New BSD License
*
* Copyright © 2007-2015, Ivan Enderlin. All rights reserved.
* Copyright © 2007-2015, Hoa community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -41,17 +41,15 @@ namespace Hoa\Compiler\Exception;
*
* Extending the \Hoa\Compiler\Exception class.
*
* @author Ivan Enderlin <ivan.enderlin@hoa-project.net>
* @copyright Copyright © 2007-2015 Ivan Enderlin.
* @copyright Copyright © 2007-2015 Hoa community
* @license New BSD License
*/

class UnrecognizedToken extends Exception {

class UnrecognizedToken extends Exception
{
/**
* Column.
*
* @var \Hoa\Compiler\Exception\UnrecognizedToken int
* @var int
*/
protected $column = 0;

@@ -60,7 +58,6 @@ class UnrecognizedToken extends Exception {
/**
* Override line and add column support.
*
* @access public
* @param string $message Formatted message.
* @param int $code Code (the ID).
* @param array $arg RaiseError string arguments.
@@ -68,8 +65,8 @@ class UnrecognizedToken extends Exception {
* @param int $column Column.
* @return void
*/
public function __construct ( $message, $code, $arg, $line, $column ) {
public function __construct($message, $code, $arg, $line, $column)
{
parent::__construct($message, $code, $arg);

$this->line = $line;
@@ -81,11 +78,10 @@ class UnrecognizedToken extends Exception {
/**
* Get column.
*
* @access public
* @return int
*/
public function getColumn ( ) {
public function getColumn()
{
return $this->column;
}
}

+ 202
- 227
Ll1.php View File

@@ -8,7 +8,7 @@
*
* New BSD License
*
* Copyright © 2007-2015, Ivan Enderlin. All rights reserved.
* Copyright © 2007-2015, Hoa community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -47,19 +47,17 @@ _define('__', '__');
*
* Provide an abstract LL(1) compiler, based on sub-automata and stacks.
*
* @author Ivan Enderlin <ivan.enderlin@hoa-project.net>
* @copyright Copyright © 2007-2015 Ivan Enderlin.
* @copyright Copyright © 2007-2015 Hoa community
* @license New BSD License
*/

abstract class Ll1 {

abstract class Ll1
{
/**
* Initial line.
* If we try to compile a code inside another code, the initial line would
* not probably be 0.
*
* @var \Hoa\Compiler\Ll1 int
* @var int
*/
protected $_initialLine = 0;

@@ -74,7 +72,7 @@ abstract class Ll1 {
* '#/\*(.|\n)*\*\/' // block comment
* ]
*
* @var \Hoa\Compiler\Ll1 array
* @var array
*/
protected $_skip = [];

@@ -106,7 +104,7 @@ abstract class Ll1 {
* ]
* ]
*
* @var \Hoa\Compiler\Ll1 array
* @var array
*/
protected $_tokens = [];

@@ -143,7 +141,7 @@ abstract class Ll1 {
* Note: the constant __ or the string '__' must be used to represent the
* null/unrecognized/error state.
*
* @var \Hoa\Compiler\Ll1 array
* @var array
*/
protected $_states = [];

@@ -158,7 +156,7 @@ abstract class Ll1 {
* ['OK']
* ]
*
* @var \Hoa\Compiler\Ll1 array
* @var array
*/
protected $_terminal = [];

@@ -197,7 +195,7 @@ abstract class Ll1 {
* Note: tokens and states should be declared in the strict same order as
* defined previously.
*
* @var \Hoa\Compiler\Ll1 array
* @var array
*/
protected $_transitions = [];

@@ -269,7 +267,7 @@ abstract class Ll1 {
a comma. Thus: 7,f is equivalent to make an epsilon-transition to the
* automata 7, then consume the action f.
*
* @var \Hoa\Compiler\Ll1 array
* @var array
*/
protected $_actions = [];

@@ -281,42 +279,42 @@ abstract class Ll1 {
/**
* Recursive stack.
*
* @var \Hoa\Compiler\Ll1 array
* @var array
*/
private $_stack = [];

/**
* Buffers.
*
* @var \Hoa\Compiler\Ll1 array
* @var array
*/
protected $buffers = [];

/**
* Current token's line.
*
* @var \Hoa\Compiler\Ll1 int
* @var int
*/
protected $line = 0;

/**
* Current token's column.
*
* @var \Hoa\Compiler\Ll1 int
* @var int
*/
protected $column = 0;

/**
* Cache compiling result.
*
* @var \Hoa\Compiler\Ll1 array
* @var array
*/
protected static $_cache = [];

/**
* Whether cache is enabled or not.
*
* @var \Hoa\Compiler\Ll1 bool
* @var bool
*/
protected static $_cacheEnabled = true;

@@ -325,7 +323,6 @@ abstract class Ll1 {
/**
* Singleton, and set parameters.
*
* @access public
* @param array $skip Skip.
* @param array $tokens Tokens.
* @param array $states States.
@@ -335,14 +332,15 @@ abstract class Ll1 {
* @param array $names Names of automata.
* @return void
*/
public function __construct ( Array $skip,
Array $tokens,
Array $states,
Array $terminal,
Array $transitions,
Array $actions,
Array $names = [] ) {

public function __construct(
Array $skip,
Array $tokens,
Array $states,
Array $terminal,
Array $transitions,
Array $actions,
Array $names = []
) {
$this->setSkip($skip);
$this->setTokens($tokens);
$this->setStates($states);
@@ -357,19 +355,19 @@ abstract class Ll1 {
/**
* Compile a source code.
*
* @access public
* @param string $in Source code.
* @return void
* @throws \Hoa\Compiler\Exception\FinalStateHasNotBeenReached
* @throws \Hoa\Compiler\Exception\IllegalToken
*/
public function compile ( $in ) {
public function compile($in)
{
$cacheId = md5($in);

if( true === self::$_cacheEnabled
&& true === array_key_exists($cacheId, self::$_cache))
if (true === self::$_cacheEnabled &&
true === array_key_exists($cacheId, self::$_cache)) {
return self::$_cache[$cacheId];
}

$d = 0;
$c = 0; // current automata.
@@ -393,25 +391,26 @@ abstract class Ll1 {

$this->pre($in);

for($i = 0, $max = strlen($in); $i <= $max; $i++) {
for ($i = 0, $max = strlen($in); $i <= $max; $i++) {

//echo "\n---\n\n";

// End of parsing (not automata).
if($i == $max) {

while( $c > 0
&& in_array($this->_states[$c][$nextState], $this->_terminal[$c]))
if ($i == $max) {
while ($c > 0 &&
in_array($this->_states[$c][$nextState], $this->_terminal[$c])) {
list($c, $nextState, ) = array_pop($this->_stack);
}

if( in_array($this->_states[$c][$nextState], $this->_terminal[$c])
&& 0 === $c
&& true === $this->end()) {
if (in_array($this->_states[$c][$nextState], $this->_terminal[$c]) &&
0 === $c &&
true === $this->end()) {

//echo '*********** END REACHED **********' . "\n";

if(true === self::$_cacheEnabled)
if (true === self::$_cacheEnabled) {
self::$_cache[$cacheId] = $this->getResult();
}

return true;
}
@@ -426,40 +425,35 @@ abstract class Ll1 {
$nextChar = $in[$i];

// Skip.
if(isset($_skip[$nextChar])) {

if($nextChar == "\n") {

if (isset($_skip[$nextChar])) {
if ("\n" === $nextChar) {
$line++;
$column = 0;
}
else
} else {
$column++;
}

continue;
}
else {

} else {
$continue = false;
$handle = substr($in, $i);

foreach($_skip as $sk => $e) {

if($sk[0] != '#')
foreach ($_skip as $sk => $e) {
if ($sk[0] != '#') {
continue;
}

$sk = str_replace('#', '\#', substr($sk, 1));

if(0 != preg_match('#^(' . $sk . ')#u', $handle, $match)) {

if (0 != preg_match('#^(' . $sk . ')#u', $handle, $match)) {
$strlen = strlen($match[1]);

if($strlen > 0) {

if(false !== $offset = strrpos($match[1], "\n"))
if ($strlen > 0) {
if (false !== $offset = strrpos($match[1], "\n")) {
$column = $strlen - $offset - 1;
else
} else {
$column += $strlen;
}

$line += substr_count($match[1], "\n");
$i += $strlen - 1;
@@ -470,28 +464,28 @@ abstract class Ll1 {
}
}

if(true === $continue)
if (true === $continue) {
continue;
}
}

// Epsilon-transition.
$epsilon = false;
while( array_key_exists($nextToken, $this->_actions[$c][$nextState])
&& (
(
is_array($this->_actions[$c][$nextState][$nextToken])
&& 0 < $foo = $this->_actions[$c][$nextState][$nextToken][0]
)
|| (
is_int($this->_actions[$c][$nextState][$nextToken])
&& 0 < $foo = $this->_actions[$c][$nextState][$nextToken]
)
while (array_key_exists($nextToken, $this->_actions[$c][$nextState]) &&
(
(
is_array($this->_actions[$c][$nextState][$nextToken]) &&
0 < $foo = $this->_actions[$c][$nextState][$nextToken][0]
) ||
(
is_int($this->_actions[$c][$nextState][$nextToken]) &&
0 < $foo = $this->_actions[$c][$nextState][$nextToken]
)
)
) {

) {
$epsilon = true;

if($_actions[$c] == 0) {
if ($_actions[$c] == 0) {

//echo '*** Change automata (up to ' . ($foo - 1) . ')' . "\n";

@@ -509,56 +503,49 @@ abstract class Ll1 {
$_actions[$c] = 0;

$d++;
}
elseif($_actions[$c] == 2) {

} elseif ($_actions[$c] == 2) {
$_actions[$c] = 0;

break;
}
}

if(true === $epsilon) {

if (true === $epsilon) {
$epsilon = false;
$nextToken = false;
}

// Token.
if(isset($_tokens[$nextChar])) {

if (isset($_tokens[$nextChar])) {
$token = $nextChar;
$nextToken = $_tokens[$token];

if($nextChar == "\n") {

if ("\n" === $nextChar) {
$line++;
$column = 0;
}
else
} else {
$column++;
}
else {

}
} else {
$nextToken = false;
$handle = substr($in, $i);

foreach($_tokens as $token => $e) {

if($token[0] != '#')
foreach ($_tokens as $token => $e) {
if ('#' !== $token[0]) {
continue;
}

$ntoken = str_replace('#', '\#', substr($token, 1));

if(0 != preg_match('#^(' . $ntoken . ')#u', $handle, $match)) {

if (0 != preg_match('#^(' . $ntoken . ')#u', $handle, $match)) {
$strlen = strlen($match[1]);

if($strlen > 0) {

if(false !== $offset = strrpos($match[1], "\n"))
if ($strlen > 0) {
if (false !== $offset = strrpos($match[1], "\n")) {
$column = $strlen - $offset - 1;
else
} else {
$column += $strlen;
}

$nextChar = $match[1];
$nextToken = $e;
@@ -579,26 +566,25 @@ abstract class Ll1 {
*/

// Got it!
if(false !== $nextToken) {

if(is_array($this->_actions[$c][$nextState][$nextToken]))
if (false !== $nextToken) {
if (is_array($this->_actions[$c][$nextState][$nextToken])) {
$nextAction = $this->_actions[$c][$nextState][$nextToken][1];
else
} else {
$nextAction = $this->_actions[$c][$nextState][$nextToken];
}
$nextState = $_states[$this->_transitions[$c][$nextState][$nextToken]];
}

// Oh :-(.
if(false === $nextToken || $nextState === $_states['__']) {

if (false === $nextToken || $nextState === $_states['__']) {
$pop = array_pop($this->_stack);
$d--;

// Go back to a parent automata.
if( (in_array($this->_states[$c][$nextState], $this->_terminal[$c])
&& null !== $pop)
|| ($nextState === $_states['__']
&& null !== $pop)) {
if ((in_array($this->_states[$c][$nextState], $this->_terminal[$c]) &&
null !== $pop) ||
($nextState === $_states['__'] &&
null !== $pop)) {

//echo '!!! Change automata (down)' . "\n";

@@ -625,7 +611,9 @@ abstract class Ll1 {
'Illegal token at line ' . ($this->line + 1) . ' and column ' .
($this->column + 1) . "\n" . $error . "\n" .
str_repeat(' ', $this->column) . '↑',
0, [], $this->line + 1, $this->column + 1
1,
[],
$this->line + 1, $this->column + 1
);
}

@@ -637,18 +625,17 @@ abstract class Ll1 {
$this->buffers[-1] = $nextChar;

// Special actions.
if($nextAction < 0) {

if ($nextAction < 0) {
$buffer = abs($nextAction);

if(($buffer & 1) == 0)
if (($buffer & 1) == 0) {
$this->buffers[($buffer - 2) / 2] = null;
else {

} else {
$buffer = ($buffer - 1) / 2;

if(!(isset($this->buffers[$buffer])))
if (!(isset($this->buffers[$buffer]))) {
$this->buffers[$buffer] = null;
}

$this->buffers[$buffer] .= $nextChar;
}
@@ -656,8 +643,9 @@ abstract class Ll1 {
continue;
}

if(0 !== $nextAction)
if (0 !== $nextAction) {
$this->consume($nextAction);
}
}

return;
@@ -667,52 +655,47 @@ abstract class Ll1 {
* Consume actions.
* Please, see the actions table definition to learn more.
*
* @access protected
* @param int $action Action.
* @return void
*/
abstract protected function consume ( $action );
abstract protected function consume($action);

/**
* Compute source code before compiling it.
*
* @access protected
* @param string &$in Source code.
* @return void
*/
protected function pre ( &$in ) {
protected function pre(&$in)
{
return;
}

/**
* Verify compiler state when ending the source code.
*
* @access protected
* @return bool
*/
protected function end ( ) {
protected function end()
{
return true;
}

/**
* Get the result of the compiling.
*
* @access public
* @return mixed
*/
abstract public function getResult ( );
abstract public function getResult();

/**
* Set initial line.
*
* @access public
* @param int $line Initial line.
* @return int
*/
public function setInitialLine ( $line ) {
public function setInitialLine($line)
{
$old = $this->_initialLine;
$this->_initialLine = $line;

@@ -722,12 +705,11 @@ abstract class Ll1 {
/**
* Set tokens to skip.
*
* @access public
* @param array $skip Skip.
* @return array
*/
public function setSkip ( Array $skip ) {
public function setSkip(Array $skip)
{
$old = $this->_skip;
$this->_skip = $skip;

@@ -738,12 +720,11 @@ abstract class Ll1 {
/**
* Set tokens.
*
* @access public
* @param array $tokens Tokens.
* @return array
*/
public function setTokens ( Array $tokens ) {
public function setTokens(Array $tokens)
{
$old = $this->_tokens;
$this->_tokens = $tokens;

@@ -753,12 +734,11 @@ abstract class Ll1 {
/**
* Set states.
*
* @access public
* @param array $states States.
* @return array
*/
public function setStates ( Array $states ) {
public function setStates(Array $states)
{
$old = $this->_states;
$this->_states = $states;

@@ -768,12 +748,11 @@ abstract class Ll1 {
/**
* Set terminal states.
*
* @access public
* @param array $terminal Terminal states.
* @return array
*/
public function setTerminal ( Array $terminal ) {
public function setTerminal(Array $terminal)
{
$old = $this->_terminal;
$this->_terminal = $terminal;

@@ -783,12 +762,11 @@ abstract class Ll1 {
/**
* Set transitions table.
*
* @access public
* @param array $transitions Transitions table.
* @return array
*/
public function setTransitions ( Array $transitions ) {
public function setTransitions(Array $transitions)
{
$old = $this->_transitions;
$this->_transitions = $transitions;

@@ -798,17 +776,20 @@ abstract class Ll1 {
/**
* Set actions table.
*
* @access public
* @param array $actions Actions table.
* @return array
*/
public function setActions ( Array $actions ) {
foreach($actions as $e => $automata)
foreach($automata as $i => $state)
foreach($state as $j => $token)
if(0 != preg_match('#^(\d+),(.*)$#', $token, $matches))
public function setActions(Array $actions)
{
foreach ($actions as $e => $automata) {
foreach ($automata as $i => $state) {
foreach ($state as $j => $token) {
if (0 != preg_match('#^(\d+),(.*)$#', $token, $matches)) {
$actions[$e][$i][$j] = [(int) $matches[1], $matches[2]];
}
}
}
}

$old = $this->_actions;
$this->_actions = $actions;
@@ -819,12 +800,11 @@ abstract class Ll1 {
/**
* Set names of automata.
*
* @access public
* @param array $names Names of automata.
* @return array
*/
public function setNames ( Array $names ) {
public function setNames(Array $names)
{
$old = $this->_names;
$this->_names = $names;

@@ -834,99 +814,90 @@ abstract class Ll1 {
/**
* Get initial line.
*
* @access public
* @return int
*/
public function getInitialLine ( ) {
public function getInitialLine()
{
return $this->_initialLine;
}

/**
* Get skip tokens.
*
* @access public
* @return array
*/
public function getSkip ( ) {
public function getSkip()
{
return $this->_skip;
}

/**
* Get tokens.
*
* @access public
* @return array
*/
public function getTokens ( ) {
public function getTokens()
{
return $this->_tokens;
}

/**
* Get states.
*
* @access public
* @return array
*/
public function getStates ( ) {
public function getStates()
{
return $this->_states;
}

/**
* Get terminal states.
*
* @access public
* @return array
*/
public function getTerminal ( ) {
public function getTerminal()
{
return $this->_terminal;
}

/**
* Get transitions table.
*
* @access public
* @return array
*/
public function getTransitions ( ) {
public function getTransitions()
{
return $this->_transitions;
}

/**
* Get actions table.
*
* @access public
* @return array
*/
public function getActions ( ) {
public function getActions()
{
return $this->_actions;
}

/**
* Get names of automata.
*
* @access public
* @return array
*/
public function getNames ( ) {
public function getNames()
{
return $this->_names;
}

/**
* Enable cache
*
* @access public
* @return bool
*/
public static function enableCache ( ) {
public static function enableCache()
{
$old = self::$_cacheEnabled;
self::$_cacheEnabled = true;

@@ -936,11 +907,10 @@ abstract class Ll1 {
/**
* Disable cache
*
* @access public
* @return bool
*/
public static function disableCache ( ) {
public static function disableCache()
{
$old = self::$_cacheEnabled;
self::$_cacheEnabled = false;

@@ -950,87 +920,92 @@ abstract class Ll1 {
/**
* Transform automatas into DOT language.
*
* @access public
* @return void
*/
public function __toString ( ) {

$out = 'digraph ' . str_replace('\\', '', get_class($this)) . ' {' .
"\n" .
' rankdir=LR;' . "\n" .
' label="Automata of ' .
str_replace('\\', '\\\\', get_class($this)) . '";';
public function __toString()
{
$out =
'digraph ' . str_replace('\\', '', get_class($this)) . ' {' .
"\n" .
' rankdir=LR;' . "\n" .
' label="Automata of ' .
str_replace('\\', '\\\\', get_class($this)) . '";';

$transitions = array_reverse($this->_transitions, true);

foreach($transitions as $e => $automata) {

$out .= "\n\n" . ' subgraph cluster_' . $e . ' {' . "\n" .
' label="Automata #' . $e .
(isset($this->_names[$e])
? ' (' . str_replace('"', '\\"', $this->_names[$e]) . ')'
: '') . '";' . "\n";

if(!empty($this->_terminal[$e]))
$out .= ' node[shape=doublecircle] "' . $e . '_' .
implode('" "' . $e . '_', $this->_terminal[$e]) . '";' . "\n";
foreach ($transitions as $e => $automata) {
$out .=
"\n\n" . ' subgraph cluster_' . $e . ' {' . "\n" .
' label="Automata #' . $e .
(isset($this->_names[$e])
? ' (' . str_replace('"', '\\"', $this->_names[$e]) . ')'
: '') .
'";' . "\n";

if (!empty($this->_terminal[$e])) {
$out .=
' node[shape=doublecircle] "' . $e . '_' .
implode('" "' . $e . '_', $this->_terminal[$e]) . '";' . "\n";
}

$out .= ' node[shape=circle];' . "\n";

foreach($this->_states[$e] as $i => $state) {

foreach ($this->_states[$e] as $i => $state) {
$name = [];
$label = $state;

if(__ != $state) {

foreach($this->_transitions[$e][$i] as $j => $foo) {

if (__ != $state) {
foreach ($this->_transitions[$e][$i] as $j => $foo) {
$ep = $this->_actions[$e][$i][$j];

if(is_array($ep))
if (is_array($ep)) {
$ep = $ep[0];
}

if(is_int($ep)) {

if (is_int($ep)) {
$ep--;

if(0 < $ep && !isset($name[$ep]))
if (0 < $ep && !isset($name[$ep])) {
$name[$ep] = $ep;
}
}
}

if(!empty($name))
if (!empty($name)) {
$label .= ' (' . implode(', ', $name) . ')';
}

$out .= ' "' . $e . '_' . $state . '" ' .
'[label="' . $label . '"];' . "\n";
$out .=
' "' . $e . '_' . $state . '" ' .
'[label="' . $label . '"];' . "\n";
}
}

foreach($automata as $i => $transition) {

foreach ($automata as $i => $transition) {
$transition = array_reverse($transition, true);

foreach($transition as $j => $state)
if( __ != $this->_states[$e][$i]
foreach ($transition as $j => $state) {
if (__ != $this->_states[$e][$i]
&& __ != $state) {

$label = str_replace('\\', '\\\\', $this->_tokens[$e][$j]);
$label = str_replace('"', '\\"', $label);

if('#' == $label[0])
if ('#' === $label[0]) {
$label = substr($label, 1);
}

$out .= ' "' . $e . '_' . $this->_states[$e][$i] .
'" -> "' . $e . '_' . $state . '"' .
' [label="' . $label . '"];' . "\n";
$out .=
' "' . $e . '_' . $this->_states[$e][$i] .
'" -> "' . $e . '_' . $state . '"' .
' [label="' . $label . '"];' . "\n";
}
}
}

$out .= ' node[shape=point,label=""] "' . $e . '_";' . "\n" .
' "' . $e . '_" -> "' . $e . '_GO";' . "\n" .
' }';
$out .=
' node[shape=point,label=""] "' . $e . '_";' . "\n" .
' "' . $e . '_" -> "' . $e . '_GO";' . "\n" .
' }';
}

$out .= "\n" . '}' . "\n";


+ 72
- 57
Llk/Lexer.php View File

@@ -8,7 +8,7 @@
*
* New BSD License
*
* Copyright © 2007-2015, Ivan Enderlin. All rights reserved.
* Copyright © 2007-2015, Hoa community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -43,39 +43,36 @@ use Hoa\Compiler;
*