/** * The entry method. * * @return int */ public function main() { while (false !== ($c = $this->getOption($v))) { switch ($c) { case 'h': case '?': return $this->usage(); case '__ambiguous': $this->resolveOptionAmbiguity($v); break; } } $this->parser->listInputs($expression); $compiler = Compiler\Llk::load(new File\Read('hoa://Library/Math/Arithmetic.pp')); $visitor = new Math\Visitor\Arithmetic(); $dump = new Compiler\Visitor\Dump(); if (null !== $expression) { $ast = $compiler->parse($expression); echo $expression . ' = ' . $visitor->visit($ast), "\n"; return; } $readline = new Console\Readline(); $readline->setAutocompleter(new Console\Readline\Autocompleter\Word(array_merge(array_keys($visitor->getConstants()->getArrayCopy()), array_keys($visitor->getFunctions()->getArrayCopy())))); $handle = null; $expression = 'h'; do { switch ($expression) { case 'h': case 'help': echo 'Usage:', "\n", ' h[elp] to print this help;', "\n", ' c[onstants] to print available constants;', "\n", ' f[unctions] to print available functions;', "\n", ' e[xpression] to print the current expression;', "\n", ' d[ump] to dump the tree of the expression;', "\n", ' q[uit] to quit.', "\n"; break; case 'c': case 'constants': echo implode(', ', array_keys($visitor->getConstants()->getArrayCopy())), "\n"; break; case 'f': case 'functions': echo implode(', ', array_keys($visitor->getFunctions()->getArrayCopy())), "\n"; break; case 'e': case 'expression': echo $handle, "\n"; break; case 'd': case 'dump': if (null === $handle) { echo 'Type a valid expression before (“> 39 + 3”).', "\n"; } else { echo $dump->visit($compiler->parse($handle)), "\n"; } break; case 'q': case 'quit': break 2; default: if (null === $expression) { break; } try { echo $visitor->visit($compiler->parse($expression)), "\n"; } catch (Compiler\Exception $e) { echo $e->getMessage(), "\n"; break; } $handle = $expression; break; } } while (false !== ($expression = $readline->readLine('> '))); return; }
public function case_whole_process() { $_grammar = <<<GRAMMAR %skip space \\s // Scalars. %token true true %token false false %token null null // Strings. %token quote_ " -> string %token string:string [^"]+ %token string:_quote " -> default // Objects. %token brace_ { %token _brace } // Arrays. %token bracket_ \\[ %token _bracket \\] // Rest. %token colon : %token comma , %token number \\d+ value: <true> | <false> | <null> | string() | object() | array() | number() string: ::quote_:: <string> ::_quote:: number: <number> #object: ::brace_:: pair() ( ::comma:: pair() )* ::_brace:: #pair: string() ::colon:: value() #array: ::bracket_:: value() ( ::comma:: value() )* ::_bracket:: GRAMMAR; $_result = <<<GRAMMAR > #object > > #pair > > > token(string:string, foo) > > > token(true, true) > > #pair > > > token(string:string, bar) > > > #array > > > > token(null, null) > > > > token(number, 42) GRAMMAR; $this->given($grammar = new File\ReadWrite('hoa://Test/Vfs/Json.pp?type=file'), $grammar->writeAll($_grammar), $compiler = LUT\Llk::load($grammar))->when($ast = $compiler->parse('{"foo": true, "bar": [null, 42]}'))->then->object($ast)->given($dump = new LUT\Visitor\Dump())->when($result = $dump->visit($ast))->then->string($result)->isEqualTo($_result); }