On Github K-Phoen / slides-hoa-compiler
Écrire un parseur SQL ? Pourquoi donc ?
Un langage est un ensemble de mots dont les enchainements respectent une structure. Chaque mot est une séquence de symboles appartenant à un alphabet.
Autrement dit : langage = notation conventionnelle destinée à formuler des idées.
Yeah, sure.
SELECT name FROM person SELECT name, age FROM person SELECT p.name, age FROM person AS p SELECT p.name, age, j.title AS job FROM person AS p, job j
// keywords %token select SELECT %token from FROM %token as AS // identifiers %token identifier [a-zA-Z][a-zA-Z0-9_]* // rest %token comma , %token dot .
#TableIdentifier:
<identifier> (::as::? <identifier>)?
#ColumnIdentifier:
<identifier>
| TableIdentifier() ::dot:: <identifier>
#SelectExpression:
ColumnIdentifier() (::as::? <identifier>)?
#SelectClause:
::select:: SelectExpression() (::comma:: SelectExpression())*
#FromClause:
::from:: TableIdentifier() (::comma:: TableIdentifier())*
#SelectQuery:
SelectClause() FromClause()
SELECT name, age FROM person
# namespace token name token value offset ---------------------------------------------------------- 0 default select SELECT 0 1 default identifier name 7 2 default comma , 11 3 default identifier age 13 4 default from FROM 17 5 default identifier person 22 6 default EOF 28
> #SelectQuery > > #SelectClause > > > #SelectExpression > > > > #ColumnIdentifier > > > > > token(identifier, name) > > > #SelectExpression > > > > #ColumnIdentifier > > > > > token(identifier, age) > > #FromClause > > > #TableIdentifier > > > > token(identifier, person)
class PrettyPrinter implements Hoa\Visitor\Visit {
public function visit(Hoa\Visitor\Element $element, &$handle = null, $eldnah = null) {
switch ($element->getId()) {
case '#SelectClause':
$selectedExpressions = array();
foreach ($element->getChildren() as $child)
$selectedExpressions[] = $child->accept($this, $handle, $eldnah);
return 'SELECT ' . implode(', ', $selectedExpressions);
case '#FromClause':
$tables = array();
foreach ($element->getChildren() as $child)
$tables[] = $child->accept($this, $handle, $eldnah);
return "\n" . 'FROM '. implode(', ', $tables);
// ...
}
}
}
$sampler = new Hoa\Compiler\Llk\Sampler\Coverage(
// Grammar.
Hoa\Compiler\Llk\Llk::load(new Hoa\File\Read('sql_sample.pp')),
// Token sampler.
new Hoa\Regex\Visitor\Isotropic(new Hoa\Math\Sampler\Random()),
// Length.
6
);
foreach ($sampler as $i => $data)
echo $i, ' => ', $data, "\n";
0 => SELECT v28__ AS Js32_B0 , w FROM T4 AS FO4Z0_ , y__ b3x_n , t3 1 => SELECT wZ_ AS i0E_6 , Od , zl82Q_ FROM e_bNTB AS I8_d___u , X AS yl2 2 => SELECT lBp FROM xV_v93Y AS j2a4991_
Technique utilisée dans le cadre du Grammar-Based testing