Hi Shawn,

check out phpDocumentor, it has a class named Parser that does exactly what
you need.

You can get the latest release at http://sourceforge.net/projects/phpdocu
nightly cvs builds are at http://developer.phpdoc.org/downloads

In CVS, there are 2 parsers to choose from, and both are very stable, but
the CVS build of phpDocumentorTParser is MUCH faster (up to 11 times faster
depending on the filesize) but requires php 4.3.0.  Look in
phpDocumentor/Parser.inc and phpDocumentor/phpDocumentorTParser.inc in CVS,
and in ./Parser.inc in the 1.1.0 release.

You would only need to create an object with a method HandleEvent like:
class receive {
    function HandleEvent($event,$data) {
        if ($event != PHPDOCUMENTOR_EVENT_NEWSTATE) {
            if ($data->getType() == 'function' && $data->name == 'someFunc')
            {
                 $source = $data->getSource();
            }
        }
    }
}

Then, modify Parser::parse() by changing the line:

            if ($this->p_flags['get_source'])
            {
                if ($pevent == PARSER_EVENT_FUNCTION)
                {
                    $this->wp->retrievesource("function $word");
                    $this->p_flags['get_source'] = false;
                    $this->p_flags['getting_source'] = true;
                }
            }

to:

            if (true)
            {
                if ($pevent == PARSER_EVENT_FUNCTION)
                {
                    $this->wp->retrievesource("function $word");
                    $this->p_flags['get_source'] = false;
                    $this->p_flags['getting_source'] = true;
                }
            }

Alternately, you can get the cvs build and use the new phpDocumentorTParser
that takes advantage of PHP 4.3.0's stable tokenizer extension
(http://www.php.net/tokenizer) to parse faster.  The line to replace in that
class is phpDocumentorTParser::parse():

            if ($this->_pf_get_source)
            {
                if ($pevent == PARSER_EVENT_FUNCTION)
                {
                    $this->_wp->retrievesource($word);
                    $this->_pf_get_source = false;
                    $this->_pf_getting_source = true;
                }
            }

change to:

            if (true)
            {
                if ($pevent == PARSER_EVENT_FUNCTION)
                {
                    $this->_wp->retrievesource($word);
                    $this->_pf_get_source = false;
                    $this->_pf_getting_source = true;
                }
            }


Here's the complete code you need to write (except for the modifications
above):

<?php
// change the path to be that which is necessary
include_once("phpDocumentor/WordParser.inc");
include_once("phpDocumentor/EventStack.inc");
include_once("phpDocumentor/ParserData.inc");
include_once("phpDocumentor/InlineTags.inc");
include_once("phpDocumentor/DocBlockTags.inc");
include_once("phpDocumentor/DescHTML.inc");
include_once("phpDocumentor/ParserDocBlock.inc");
include_once("phpDocumentor/ParserElements.inc");
include_once("phpDocumentor/Parser.inc");
include_once("phpDocumentor/phpDocumentorTWordParser.inc");
include_once("phpDocumentor/phpDocumentorTParser.inc");


class someFunc_receive {
    function HandleEvent($event,$data) {
        if ($event != PHPDOCUMENTOR_EVENT_NEWSTATE) {
            if ($data->getType() == 'function' && $data->name == 'someFunc')
            {
                 $source = $data->getSource();
                 {do something with the source}
            }
        }
    }
}

$fp = fopen('/path/to/file.php','r');
$contents = fread($fp,filesize('/path/to/file.php'));

$parser = new phpDocumentorTParser; // or $parser = new Parser;
$receiver = new someFunc_receive;

$parser->subscribe('*',$receiver);
$parser->parse($contents, ''); // the other parameters are for
phpDocumentor, you won't need them

?>

You can also modify the Parser class to avoid publishing anything that isn't
necessary, and speed things up for your specific case.

It is possible to do some other method, but you need to be able to parse
strings, and recognize functions in a class otherwise code like this will
break your parser:

<?php
class myclass
{
 // {this brace is parsed even though it's in a comment
  /* } so is this one and this one } */
    function someFunc() {
        $data = "Now you're up a creek without a paddle! }";
    }
}

function someFunc() {
}
?>

In the end, you'll be forced to reinvent the wheel at great personal agony
:).  Go with phpDocumentor, and your life will be smooth sailing.
Incidentally, the source returned by the phpDocumentorTParser is an array of
tokens from the tokenizer, so the code will already be split up, if that is
useful.  If not, you can easily join the code back into a string using:

$total = '';
foreach($source as $item) {
    if (is_array($item)) $item = $item[1]; // $item[0] is the token
    $total .= $item;
}

Take care,
Greg
--
phpDocumentor
http://www.phpdoc.org

"Shawn McKenzie" <[EMAIL PROTECTED]> wrote in message
[EMAIL PROTECTED]">news:[EMAIL PROTECTED]...
> I need to parse some source code to find the contents of a specific
> function.  The only way I can think of is to load the source file into a
> string find the function by name and parse the text in the string and find
> the end brace of the function, made difficult by the existence of all the
> other braces that may be there (if, while, switch, foreach, etc...).
> Anybody have some code to do this???
>
> function someFunc() {
>
> if(something) {
>    something...
> }
>
> while(something) {
>    something...
> }
>
> } // So I need the code from the beginning of the function to here
>
> TIA
> -Shawn
>
>



-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to