begin process at 2012 05 27 19:47:15
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Class et Objet ( POO )

 > CRÉER UN PARSEUR LL

CRÉER UN PARSEUR LL


 Information sur la source

Note :
9,5 / 10 - par 2 personnes
9,50 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Class et Objet ( POO ) Classé sous :parseur, parsing, chaines, ll, llp Niveau :Initié Date de création :15/04/2011 Vu :3 129

Auteur : Morphinof

Ecrire un message privé
Commentaire sur cette source (9)
Ajouter un commentaire et/ou une note

 Description

Les parseurs, vous les utilisez mais vous ne savez pas forcement comment ils marchent.

Voici un exemple de parseur ll simple sans lexer :

Son fonctionnement est très simple, il commence par consommer la plus petite entité du flux : le caractère avec la fonction readChar, et a partir de là suivent un lot de fonctions qui permettent au fur et a mesure des entités plus complexes comme les nombres, les chaines etc. et ainsi définir les règles de grammaire du parsing.

Ce parseur contient deux buffers : le buffer principal qui contient le flux à parser et le buffer de lecture qui contient ce qui a été lu.

Il reste extrêmement basique bien entendu ^^

Source

  • <?php
  • define('BR', '<br />');
  • define('NO_ERROR', -1);
  • define('EMPTY_BUFFER', 0);
  • define('INVALID_DIGIT', 1);
  • define('INVALID_VARNAME', 2);
  • define('VAR_TAG_EXPECTED', 3);
  • define('CLOSE_TAG_EXPECTED', 4);
  • /*
  • * Specifics chars
  • */
  • define('VAR_TAG', '$');
  • define('CLOSE_TAG', ';');
  • define('FLOAT_COMMA', '.');
  • abstract class LLP
  • {
  • /*
  • * Main bufer
  • */
  • private static $buffer = '';
  • private static $bSize = 0;
  • /*
  • * Read buffer
  • */
  • private static $readBuffer = '';
  • private static $rbSize = 0;
  • /*
  • * Read cursors
  • */
  • private static $cursor = 0; # Current
  • private static $index = 0; # Global
  • /*
  • * Prepare will skip following chars
  • */
  • private static $skip = array
  • (
  • ' ',
  • "\n",
  • "\t",
  • "\r"
  • );
  • /*
  • * Errors
  • */
  • private static $errorType = -1;
  • public static function getError()
  • {
  • switch (self::$errorType)
  • {
  • case 0 : $str = 'EMPTY_BUFFER'; break;
  • case 1 : $str = 'INVALID_DIGIT'; break;
  • case 2 : $str = 'INVALID_VARNAME'; break;
  • case 3 : $str = 'VAR_TAG_EXPECTED'; break;
  • case 4 : $str = 'CLOSE_TAG_EXPECTED'; break;
  • default : $str = 'NO_ERROR';
  • }
  • return 'PARSE_ERROR >> '.$str;
  • }
  • /*
  • * Returns global buffer index
  • */
  • public static function getIndex()
  • {
  • return self::$index;
  • }
  • /*
  • * Returns char at index self::$index;
  • */
  • public static function getCharAtCurrentIndex()
  • {
  • return self::$buffer[self::$index];
  • }
  • /*
  • * return current buffer index
  • */
  • public static function getCursor()
  • {
  • return self::$cursor;
  • }
  • /*
  • * Clean main buffer
  • */
  • public static function clean()
  • {
  • self::$buffer = '';
  • self::$bSize = 0;
  • self::$readBuffer = '';
  • self::$rbSize = 0;
  • self::$index = 0;
  • self::$cursor = 0;
  • }
  • /*
  • * Rturn main buffer
  • */
  • public static function buffer()
  • {
  • return self::$buffer;
  • }
  • /*
  • * Clean Read buffer
  • */
  • public static function flush()
  • {
  • $readBuffer = self::$readBuffer;
  • self::$readBuffer = '';
  • return $readBuffer;
  • }
  • /*
  • * Print buffers
  • */
  • public static function cout()
  • {
  • $out = '';
  • $out .= '<pre>';
  • $out .= 'MAIN_BUFFER >> ';
  • $out .= (strlen(self::$buffer) > 0 ? self::$buffer : 'EMPTY').BR;
  • $out .= 'READ_BUFFER >> ';
  • $out .= (strlen(self::$readBuffer) > 0 ? self::$readBuffer : 'EMPTY').BR;
  • $out .= '</pre>';
  • echo $out;
  • }
  • /*
  • * Prepare for read
  • */
  • protected static function prepare()
  • {
  • if (self::$bSize === 0)
  • {
  • self::$errorType = EMPTY_BUFFER;
  • return false;
  • }
  • self::$cursor = 0;
  • while (in_array(self::$buffer[0], self::$skip)) self::unbufferize();
  • return true;
  • }
  • /*
  • * Add text to main buffer
  • */
  • public static function bufferize($str = '')
  • {
  • if (is_string($str))
  • {
  • self::$buffer = trim($str.self::$buffer);
  • self::$bSize += strlen($str);
  • return true;
  • }
  • return false;
  • }
  • /*
  • * Eat $size left chars in main buffer
  • */
  • protected static function unbufferize($size = 1)
  • {
  • if ($size > 0)
  • {
  • if ($size <= self::$bSize)
  • {
  • self::$buffer = substr(self::$buffer, $size, self::$bSize);
  • self::$bSize -= strlen($size);
  • self::$cursor += $size;
  • self::$index += $size;
  • return true;
  • }
  • return false;
  • }
  • return false;
  • }
  • /*
  • * Private read functions
  • */
  • /*
  • * Read $size chars in main buffer and unbuferize them
  • */
  • protected static function read($size = 1)
  • {
  • if ($size > 0)
  • {
  • if ($size > self::$bSize)
  • {
  • $size = self::$bSize;
  • self::$bSize = 0;
  • }
  • self::$readBuffer .= substr(self::$buffer, 0, $size);
  • self::$rbSize += strlen($size);
  • return self::unbufferize($size);
  • }
  • return false;
  • }
  • /*
  • * Try to read any char in main buffer
  • */
  • protected static function readChar($char = NULL)
  • {
  • if (!is_null($char))
  • {
  • if (self::$buffer[0] !== $char)
  • return false;
  • }
  • return self::read();
  • }
  • /*
  • * Try to read specified digit in main buffer
  • */
  • protected static function readDigit($digit = NULL)
  • {
  • if (ctype_digit(self::$buffer[0]))
  • {
  • if (ctype_digit($digit))
  • {
  • if (self::$buffer[0] !== $digit)
  • return false;
  • }
  • return self::read();
  • }
  • return false;
  • }
  • /*
  • * Try to read a int in main buffer
  • */
  • protected static function readInteger($int)
  • {
  • if (!ctype_digit($int))
  • return false;
  • $int = strval($int);
  • $numSize = strlen($int);
  • $i = 0;
  • while ($i < $numSize)
  • {
  • if (self::readDigit($int[$i]))
  • $i++;
  • else
  • return false;
  • }
  • return true;
  • }
  • /*
  • * Try to read a float in main buffer
  • */
  • protected static function readFloat($float = '', $separator = FLOAT_COMMA)
  • {
  • $float = explode($separator, $float);
  • return self::readInteger($float[0]) &&
  • self::readChar($separator) &&
  • self::readInteger($float[1]);
  • }
  • /*
  • * Public basic read functions
  • */
  • /*
  • * Try to read specified string
  • */
  • public static function readString($str = '')
  • {
  • if (!is_string($str))
  • return false;
  • $strSize = strlen($str);
  • $i = 0;
  • while ($i < $strSize)
  • {
  • if (self::readChar($str[$i]) || self::readDigit($str[$i]))
  • $i++;
  • else
  • return false;
  • }
  • return true;
  • }
  • /*
  • * Read until next pattern
  • */
  • public static function readNext($str)
  • {
  • if (!is_string($str))
  • return false;
  • while (!self::readString($str)) ;
  • if (self::$bSize == 0) return false;
  • return true;
  • }
  • /*
  • * Read buffer until buffer contain alpha chars
  • */
  • public static function readAlpha()
  • {
  • self::prepare();
  • $count = 0;
  • while ((ctype_alpha(self::$buffer[0]) && self::readChar())) $count++;
  • if ($count > 0) return true;
  • return false;
  • }
  • /*
  • * Read buffer until buffer contain alphanum chars
  • */
  • public static function readAlphaNum()
  • {
  • self::prepare();
  • $count = 0;
  • while ((ctype_alnum(self::$buffer[0]) && self::readChar())) $count++;
  • if ($count > 0) return true;
  • return false;
  • }
  • /*
  • * Try to read a number (int or float)
  • */
  • public static function readNumber($number)
  • {
  • self::prepare();
  • if (strstr($number, FLOAT_COMMA)) return self::readFloat($number);
  • return self::readInteger($number);
  • }
  • /*
  • * Try to read a word in main buffer
  • */
  • public static function readWord($str)
  • {
  • self::prepare();
  • return self::readString($str);
  • }
  • /*
  • * Test patterned read functions
  • */
  • public static function readVar()
  • {
  • self::prepare();
  • if (self::readString(VAR_TAG))
  • {
  • self::prepare();
  • if (self::readAlpha() && !self::readAlphaNum())
  • {
  • if (self::readChar(CLOSE_TAG)) return true;
  • else self::$errorType = CLOSE_TAG_EXPECTED;
  • }
  • else
  • {
  • self::$errorType = INVALID_VARNAME;
  • }
  • }
  • else self::$errorType = VAR_TAG_EXPECTED;
  • return false;
  • }
  • }
  • define('XML_OPEN_NODE', '<');
  • define('XML_CLOSE_NODE', '>');
  • define('XML_TERMINAL_NODE', '</');
  • class NodeParser extends LLP
  • {
  • private static $currentNodeName = '';
  • private static $nodeContent = '';
  • public static function nodeName()
  • {
  • return self::$currentNodeName;
  • }
  • public static function nodeContent()
  • {
  • return self::$nodeContent;
  • }
  • public static function openNode()
  • {
  • if (parent::readString(XML_OPEN_NODE))
  • parent::flush();
  • if (parent::readAlphaNum())
  • self::$currentNodeName = parent::flush();
  • if (parent::readString(XML_CLOSE_NODE))
  • {
  • parent::flush();
  • return true;
  • }
  • return false;
  • }
  • public static function closeNode()
  • {
  • if (parent::readString(XML_TERMINAL_NODE))
  • parent::flush();
  • if (parent::readString(self::$currentNodeName))
  • parent::flush();
  • if (parent::readString(XML_CLOSE_NODE))
  • {
  • parent::flush();
  • return true;
  • }
  • return false;
  • }
  • public static function node()
  • {
  • if (self::openNode())
  • {
  • parent::readAlphaNum();
  • self::$nodeContent = parent::flush();
  • if (self::closeNode())
  • {
  • return true;
  • }
  • else
  • {
  • echo 'CLOSE_NODE_ERROR'.BR;
  • }
  • }
  • else
  • {
  • echo 'OPEN_NODE_ERROR'.BR;
  • }
  • return false;
  • }
  • }
  • LLP::bufferize('public private 4242 42.42 toto42 $titi;');
  • LLP::cout();
  • if (LLP::readWord('public'))
  • {
  • echo 'Read String : '.LLP::flush().BR;
  • }else{ echo 'Read String : FAIL at index '.LLP::getIndex().BR; }
  • if (LLP::readWord('private'))
  • {
  • echo 'Read String : '.LLP::flush().BR;
  • }else{ echo 'Read String : FAIL at index '.LLP::getIndex().BR; }
  • if (LLP::readNumber(4242))
  • {
  • echo 'Read Int : '.LLP::flush().BR;
  • }
  • else{ echo 'Read Int : FAIL at index '.LLP::getIndex().BR; LLP::cout(); }
  • if (LLP::readNumber(42.42))
  • {
  • echo 'Read Float : '.LLP::flush().BR;
  • }
  • else{ echo 'Read Float : FAIL at index '.LLP::getIndex().BR; LLP::cout(); }
  • if (LLP::readAlphaNum())
  • {
  • echo 'Read AlphaNum : '.LLP::flush().BR;
  • }else{ echo 'Read AlphaNum : FAIL at index '.LLP::getIndex().BR; }
  • if (LLP::readVar())
  • {
  • echo 'Read Var : '.LLP::flush().BR;
  • }else{ echo 'Read Var : FAIL at index '.LLP::getIndex().' : '.LLP::getError().BR; }
  • echo 'Done';
  • NodeParser::clean();
  • NodeParser::bufferize('<toto>titi</toto>');
  • NodeParser::cout();
  • if (NodeParser::node())
  • {
  • echo 'Read Node : '.XMLParser::nodeName().' with content '.XMLParser::nodeContent().BR;
  • }else{ echo 'Read Node : FAIL at index '.XMLParser::getIndex().' : '.XMLParser::getError().BR; }
  • ?>
<?php
define('BR', '<br />');

define('NO_ERROR', -1);
define('EMPTY_BUFFER', 0);
define('INVALID_DIGIT', 1);
define('INVALID_VARNAME', 2);
define('VAR_TAG_EXPECTED', 3);
define('CLOSE_TAG_EXPECTED', 4);
/*
 * Specifics chars
 */
define('VAR_TAG', '$');
define('CLOSE_TAG', ';');
define('FLOAT_COMMA', '.');

abstract class LLP
{
    /*
     * Main bufer
     */
    private static $buffer = '';
    private static $bSize = 0;
    /*
     * Read buffer
     */
    private static $readBuffer = '';
    private static $rbSize = 0;
    /*
     * Read cursors
     */
    private static $cursor = 0; # Current
    private static $index = 0; # Global
    /*
     * Prepare will skip following chars
     */
    private static $skip = array
    (
            ' ',
            "\n",
            "\t",
            "\r"
    );
    /*
     * Errors
     */
    private static $errorType = -1;

    public static function getError()
    {
        switch (self::$errorType)
        {
            case 0 : $str = 'EMPTY_BUFFER'; break;
            case 1 : $str = 'INVALID_DIGIT'; break;
            case 2 : $str = 'INVALID_VARNAME'; break;
            case 3 : $str = 'VAR_TAG_EXPECTED'; break;
            case 4 : $str = 'CLOSE_TAG_EXPECTED'; break;
            default : $str = 'NO_ERROR';
        }

        return 'PARSE_ERROR >> '.$str;
    }
    /*
     * Returns global buffer index
     */
    public static function getIndex()
    {
        return self::$index;
    }
    /*
     * Returns char at index self::$index;
     */
    public static function getCharAtCurrentIndex()
    {
        return self::$buffer[self::$index];
    }
    /*
     * return current buffer index
     */
    public static function getCursor()
    {
        return self::$cursor;
    }
    /*
     * Clean main buffer
     */
    public static function clean()
    {
        self::$buffer = '';
        self::$bSize = 0;

        self::$readBuffer = '';
        self::$rbSize = 0;

        self::$index = 0;
        self::$cursor = 0;
    }
    /*
     * Rturn main buffer
     */
    public static function buffer()
    {
        return self::$buffer;
    }
    /*
     * Clean Read buffer
     */
    public static function flush()
    {
        $readBuffer = self::$readBuffer;

        self::$readBuffer = '';

        return $readBuffer;
    }
    /*
     * Print buffers
     */
    public static function cout()
    {
        $out = '';

        $out .= '<pre>';
        $out .= 'MAIN_BUFFER >> ';
        $out .= (strlen(self::$buffer) > 0 ? self::$buffer : 'EMPTY').BR;
        $out .= 'READ_BUFFER >> ';
        $out .= (strlen(self::$readBuffer) > 0 ? self::$readBuffer : 'EMPTY').BR;
        $out .= '</pre>';

        echo $out;
    }
    /*
     * Prepare for read
     */
    protected static function prepare()
    {
        if (self::$bSize === 0)
        {
            self::$errorType = EMPTY_BUFFER;
            return false;
        }

        self::$cursor = 0;

        while (in_array(self::$buffer[0], self::$skip)) self::unbufferize();

        return true;
    }
    /*
     * Add text to main buffer
     */
    public static function bufferize($str = '')
    {
        if (is_string($str))
        {
            self::$buffer = trim($str.self::$buffer);
            self::$bSize += strlen($str);

            return true;
        }

        return false;
    }
    /*
     * Eat $size left chars in main buffer
     */
    protected static function unbufferize($size = 1)
    {
        if ($size > 0)
        {
            if ($size <= self::$bSize)
            {
                self::$buffer = substr(self::$buffer, $size, self::$bSize);
                self::$bSize -= strlen($size);

                self::$cursor += $size;
                self::$index += $size;

                return true;
            }
            return false;
        }
        return false;
    }
    
    /*
     * Private read functions
     */

    /*
     * Read $size chars in main buffer and unbuferize them
     */
    protected static function read($size = 1)
    {
        if ($size > 0)
        {
            if ($size > self::$bSize)
            {
                $size = self::$bSize;
                self::$bSize = 0;
            }

            self::$readBuffer .= substr(self::$buffer, 0, $size);
            self::$rbSize += strlen($size);

            return self::unbufferize($size);
        }
        return false;
    }
    /*
     * Try to read any char in main buffer
     */
    protected static function readChar($char = NULL)
    {
        if (!is_null($char))
        {
            if (self::$buffer[0] !== $char)
                return false;
        }
        return self::read();
    }
    /*
     * Try to read specified digit in main buffer
     */
    protected static function readDigit($digit = NULL)
    {
        if (ctype_digit(self::$buffer[0]))
        {
            if (ctype_digit($digit))
            {
                    if (self::$buffer[0] !== $digit)
                        return false;
            }
            return self::read();
        }
        return false;
    }
    /*
     * Try to read a int in main buffer
     */
    protected static function readInteger($int)
    {
        if (!ctype_digit($int))
                return false;

        $int = strval($int);
        $numSize = strlen($int);
        $i = 0;

        while ($i < $numSize)
        {
            if (self::readDigit($int[$i]))
                $i++;
            else
                return false;
        }

        return true;
    }
    /*
     * Try to read a float in main buffer
     */
    protected static function readFloat($float = '', $separator = FLOAT_COMMA)
    {
        $float = explode($separator, $float);

        return self::readInteger($float[0]) &&
               self::readChar($separator) &&
               self::readInteger($float[1]);
    }
    
    /*
     * Public basic read functions
     */

    /*
     * Try to read specified string
     */
    public static function readString($str = '')
    {
        if (!is_string($str))
            return false;

        $strSize = strlen($str);
        $i = 0;

        while ($i < $strSize)
        {
            if (self::readChar($str[$i]) || self::readDigit($str[$i]))
                $i++;
            else
                return false;
        }

        return true;
    }
    /*
     * Read until next pattern
     */
    public static function readNext($str)
    {
        if (!is_string($str))
            return false;

        while (!self::readString($str)) ;

        if (self::$bSize == 0) return false;
        
        return true;
    }
    /*
     * Read buffer until buffer contain alpha chars
     */
    public static function readAlpha()
    {
        self::prepare();

        $count = 0;
        
        while ((ctype_alpha(self::$buffer[0]) && self::readChar())) $count++;
        
        if ($count > 0) return true;

        return false;
    }
    /*
     * Read buffer until buffer contain alphanum chars
     */
    public static function readAlphaNum()
    {
        self::prepare();

        $count = 0;
        
        while ((ctype_alnum(self::$buffer[0]) && self::readChar())) $count++;

        if ($count > 0) return true;
        
        return false;
    }
    /*
     * Try to read a number (int or float)
     */
    public static function readNumber($number)
    {
        self::prepare();

        if (strstr($number, FLOAT_COMMA)) return self::readFloat($number);

        return self::readInteger($number);
    }
    /*
     * Try to read a word in main buffer
     */
    public static function readWord($str)
    {
        self::prepare();

        return self::readString($str);
    }

    /*
     * Test patterned read functions
     */

    public static function readVar()
    {
        self::prepare();

        if (self::readString(VAR_TAG))
        {
            self::prepare();
            
            if (self::readAlpha() && !self::readAlphaNum())
            {
                if (self::readChar(CLOSE_TAG)) return true;
                else self::$errorType = CLOSE_TAG_EXPECTED;
            }
            else
            {
                self::$errorType = INVALID_VARNAME;
            }
        }
        else self::$errorType = VAR_TAG_EXPECTED;

        return false;
    }
}

 define('XML_OPEN_NODE', '<');
 define('XML_CLOSE_NODE', '>');
 define('XML_TERMINAL_NODE', '</');
 
class NodeParser extends LLP
{
    private static $currentNodeName = '';
    private static $nodeContent = '';

    public static function nodeName()
    {
        return self::$currentNodeName;
    }

    public static function nodeContent()
    {
        return self::$nodeContent;
    }

    public static function openNode()
    {
        if (parent::readString(XML_OPEN_NODE))
            parent::flush();
        if (parent::readAlphaNum())
            self::$currentNodeName = parent::flush();
        if (parent::readString(XML_CLOSE_NODE))
        {
            parent::flush();
            return true;
        }
        return false;
    }

    public static function closeNode()
    {
        if (parent::readString(XML_TERMINAL_NODE))
            parent::flush();
        if (parent::readString(self::$currentNodeName))
           parent::flush();
        if (parent::readString(XML_CLOSE_NODE))
        {
            parent::flush();
            return true;
        }
        return false;
    }
    
    public static function node()
    {
        if (self::openNode())
        {
            parent::readAlphaNum();
            self::$nodeContent = parent::flush();

            if (self::closeNode())
            {
                return true;
            }
            else
            {
                echo 'CLOSE_NODE_ERROR'.BR;
            }
        }
        else
        {
            echo 'OPEN_NODE_ERROR'.BR;
        }

        return false;
    }
}

LLP::bufferize('public private 4242 42.42 toto42 $titi;');
LLP::cout();

if (LLP::readWord('public'))
{
    echo 'Read String : '.LLP::flush().BR;
}else{ echo 'Read String : FAIL at index '.LLP::getIndex().BR; }

if (LLP::readWord('private'))
{
    echo 'Read String : '.LLP::flush().BR;
}else{ echo 'Read String : FAIL at index '.LLP::getIndex().BR; }

if (LLP::readNumber(4242))
{
    echo 'Read Int : '.LLP::flush().BR;
}
else{ echo 'Read Int : FAIL at index '.LLP::getIndex().BR; LLP::cout(); }

if (LLP::readNumber(42.42))
{
    echo 'Read Float : '.LLP::flush().BR;
}
else{ echo 'Read Float : FAIL at index '.LLP::getIndex().BR; LLP::cout(); }

if (LLP::readAlphaNum())
{
    echo 'Read AlphaNum : '.LLP::flush().BR;
}else{ echo 'Read AlphaNum : FAIL at index '.LLP::getIndex().BR; }

if (LLP::readVar())
{
    echo 'Read Var : '.LLP::flush().BR;
}else{ echo 'Read Var : FAIL at index '.LLP::getIndex().' : '.LLP::getError().BR; }

echo 'Done';

NodeParser::clean();
NodeParser::bufferize('<toto>titi</toto>');
NodeParser::cout();

if (NodeParser::node())
{
    echo 'Read Node : '.XMLParser::nodeName().' with content '.XMLParser::nodeContent().BR;
}else{ echo 'Read Node : FAIL at index '.XMLParser::getIndex().' : '.XMLParser::getError().BR; }

?>

 Conclusion

Cette source est purement didactique ^^


 Sources du même auteur

Source avec Zip CLIENT / SERVEUR : LES SOCKETS
Source avec Zip DESIGN PATTERNS - CREATEURS
Source avec Zip ABSTRACTHTML GENERATOR
Source avec Zip Source avec une capture DBOC - V3.1 [AJAX][PHP5]
Source avec Zip Source avec une capture DBOC 2.0 [AJAX][PHP5]

 Sources de la même categorie

Source avec Zip GÉNÉRATION AUTOMATIQUE DE FICHIER .CLASS.PHP EN FONCTION D'U... par ig3
CLASSE D'OBJET DE CRYPTAGE ET DÉCRYPTAGE DE CHAINES DE CARAC... par 8Tnerolf8
Source avec Zip MY.DEVIANTART API par inwebo
CLASSE DE GESTION DE "VARIABLES GLOBALES D'ENVIRONNEMENT" par pifou25
Source avec Zip COLLECTION.CLASS.MIN.PHP par thunderhunter

 Sources en rapport avec celle ci

Source avec Zip LEVELPARSER par jonguignolo
Source avec Zip Source avec une capture ENCODAGE UTF16 par foisse
Source avec Zip Source avec une capture PARSEUR XML par petifa
FICHIER XML => TABLEAU ASSOCIATIF par durealex
Source avec Zip PILE/PARSEUR/LEXER/TOKENS par coucou747

Commentaires et avis

Commentaire de JLN le 18/04/2011 09:53:00 9/10

Un petit exemple d'utilisation et à quel moment l'utiliser serait un plus non négligeable pour partager avec les newbies et pas seulement avec les initiés.
Pour ma part, je trouve ce code bien fait et mérite un 9 (que je met) à cause du manque d'explications et du peu (pas) de commentaire dans le script.

Commentaire de Morphinof le 18/04/2011 10:10:30

Bonjour :)

En fait ce n'est pas un code fait pour être utilise (il n'est pas assez complet), il est purement didactique.

Ça permet de mieux comprendre comment marche un parseur LL et une manière de l'implémenter.

La fin du code comprends une partie de test pour montrer son fonctionnement après ca s'adresse quand même a des des inities c'est pas évident de tout expliquer je me suis dit que ca serait plus simple de répondre aux questions ^^

Commentaire de aKheNathOn le 18/04/2011 10:55:55

RIEN QU'UN MOT : J'ADORE !!!

J'ai bossé sur un parseur mais j'ai fait l'implémentation de manière intuitive, et après quelques refactoring je suis tombé sur quelque chose d'assez similaire, mais un peu trop lourd à mon sens.

Je l'essaye et je reviens pour te faire un retour, en tout cas merci pour ce code.

Commentaire de Morphinof le 18/04/2011 11:32:25

Coucou Akhenaton ca fait un bail ;)

Ça fait longtemps que ce code trainai dans mon repository il reste quand même très basique mais il s'occupe du parsing de base et implémenter de nouvelles "règles" sous forme de fonction reste simple.

J'attends ton retour avec impatience ;)

Commentaire de aKheNathOn le 18/04/2011 11:32:56

Petite correction à la fin de ton code, faut utiliser NodeParser au lieu de XMLParser.

En lisant le code je me rends compte que le buffer initialement utilisé est tronqué par son début à chaque itération (unbufferize), cela ne risque pas sur des gros buffers de ralentir le parsing ? Y'à t'il une raison pour laquelle on ne pourrait pas tout simplement utiliser une boucle et itérer sur un curseur qui avance sur le texte ?

Autre point, c'est que l'accès au buffer se fait de manière statique ce qui ne devrait pas trop être dérangeant, mais je me demandais pourquoi ne pas avoir utilisé des instances d'objets, ce serait la même conso mémoire, avec la possibilité de créer plusieurs instances chacune ayant son contexte ...

Sinon j'adore le côté simple ... mais j'aurais fait une classe reader à part de la classe qui parse (cela permettrait de lire un buffer ou un fichier selon le reader utilisé).

Je viens de lire un article wiki sur le sujet, je ne suis pas pour autant plus avancé ... pourrais-tu revenir un peu sur le principe de fonctionnement des parseurs LL car à priori ils ont l'air assez puissants ...


Commentaire de Morphinof le 18/04/2011 12:08:06

Oui le NodeParser c'etait un test d'heritage pour verifier que tout marchait bien et comme ce n'etait pas reelement un parseur xml j'ai change le nom mais j'ai oublie de le faire dans les test ^^

Sinon cote buffers :

J'ai mit deux buffer mais ce n'est pas comme cela qu'il faudrait procéder, en fait le readBuffer devrai être remplace par une pile fifo, surtout si on veux pouvoir créer des règles d'assignation du genre a = b la pile deviens indispensable.

Le buffer principal qui est donc le flux a parser est automatiquement tronque dans un parseur ll enfin c'est comme ca que j'ai appris a les écrire en C++ ca a l'avantage de libérer de la mémoire (en PhP on a pas cette problématique), on consomme littéralement le flux d'entrée au fur et a mesure du parsing et on empile les éléments. Cela dit peu être effectivement que il y aurait une façon plus rapide de tronquer le flux et utiliser un index marcherai bien entendu.

Pourquoi ne pas avoir instancie le buffer et l'avoir mit en statique ?
Tout simplement par pur préférence personnelle ^^ Je me suis dit que on allait parser une chose a la fois et pas deux simultanément.

Pour revenir sur le principe d'un parseur ll, l'introduction que tu trouvera la explique plutôt bien leur principe de base :

http://levee-online.org/frll1-parser.html

Mais ici mon but etait de faire la version la plus simpliste c'est a dire sans grammaire récursive avec un lexer et des token terminaux et non terminaux. Ici les règles de parsing sont de simple fonctions c'est bien plus simple a comprendre et ca marche tellement bien ^^

Commentaire de Morphinof le 18/04/2011 12:13:48

En fait il faudrai que j'écrive un tuto dessus pour bien expliquer le principe d'un parseur llk, il y a beaucoup de notions que je n'ai pas aborde dans cette source parce que je voulais qu'elle reste simple et accessible c'est pour ca que j'ai précisé sans lexer parce que la on tape dans l'implémentation de la grammaire et la c'est plus complexe.

Commentaire de aKheNathOn le 18/04/2011 14:55:01 10/10

J'ai hâte de lire ton tuto car je suis un peu imperméable aux formules mathématiques et théoriques et le site de Levee ne m'a pas plus aidé. Je trouve que la théorie des ensembles embrouille plus que n'explique, un bon tuto et une bonne dose de vulgarisation ne ferais pas de mal :))) surtout qu'après quelques recherches acharnées sur google j'ai rien trouvé de convaincant.

Bon courage pour ton tuto et merci pour cette source :)

Commentaire de Morphinof le 18/04/2011 15:53:04

Merci ^^

Pour être honnête je suis allergique aux maths aussi mais je pense que l'on peu décrire le fonctionnement sans passer par la, j'essayerai en tout cas ;)

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

menu et chaines de caractères [ par ayor ] bien le bonjour à tous, je voulais juste poser 2 petites questions : - tout d'abord, sous phpmyadmin, est-il possible de créer des champs de text Extraire que les MAJUSCULES d'une chaines de caracteres [ par sxvirus ] Bonsoir,Je cherche à extraire que les MAJUSCULES d'une chaines de caracteres mais je n'y arrive pas.Avez vous une solution , MERCI d'avance. remplacer strok par ereg [ par apz ] salut,j'utilise strok pour recuperer des sous-chaines d'une ligne dans un fichier.mais je voulais remplacer le strok (pour eviter les boucles et ainsi Découpage de chaines [ par stephtbesy ] Bonjour tout le monde,voilà mon prb... il n'y a pas de fonction lastIndexOf en php.Je souhaiterais en effet prendre juste le nom du fichier que j'uplo codes des chaines cryptées [ par fado0 ] bonjour,je cherche un code pour decryptées les chaines numeriques ou un logiciel ou un site ou je peux trouver une réponcemerci de votre aide comparaison de chaines [ par darkhorkeu ] Quelqu'un sait-il si la comparaison de chaine: "str1" == "str2" revient au meme que:!strcmp("str1","str2") merci d'avance Trier Chaines de caractère dans un fichier texte [ par jdaviaud ] Salut à tous :)Voila, j'aurais besoin d'un peu d'aide car je vois pas trop comment m'y prendre :J'ai un motur de cherche qui stoque tous les termes de Parsing et performances ... [ par guiguimac ] bonjour,je viens de reprendre un site web tout en php. son principe est le suivant : les pages html sont préparée sous formes de template que le code parsing error !?! [ par Arkko ] c cmt qu'on fait pour pas avoir cet erreur lol Parse error: parse error, unexpected $end in debug.php on line 71 PHP / NuSOAP : Xml parsing error [ par pete87150 ] Bonjour,J'ai créé un service web tout simple pour tester : [WebService(Description="Bienvenue sur le service Web de démo",Namespace="WordGeneration")]


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,624 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales