HiveBrain v1.2.0
Get Started
← Back to all entries
patternphpMinor

Parsing annotation

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
parsingannotationstackoverflow

Problem

I have implemented code for parsing annotation:

/**
 * @Route(path="sample \n test",code,value,boolean,test)
 * @access(code=false)
 * @sample as asdad asd

 * asd
 */
function sample()
{

}

$refelection = new ReflectionFunction("sample");
$pattern = "/@(\w+?)(.*?)/U";

preg_match_all($pattern, $refelection->getDocComment(), $matches);

$matches = array_combine($matches[1], $matches[2]);

foreach ($matches as $key => $value)
{
    $params = array();
    $token = token_get_all("");

    if (substr($value, 0, 1) !== "(" || substr($value, -2, -1) !== ")")
    {
        continue;
    }
    echo $key;
    $limit = count($token) - 2;
    for ($i = 2; $i < $limit; $i++)
    {
        if (array_key_exists($i + 1, $token) && $token[$i + 1] == "=")
        {
            if (!is_array($token[$i + 2]))
            {
                die("invalid");
            }

            $params[$token[$i][1]] = $token[$i + 2][1];
            $i+=3;
        }
        else
        {
            if (!is_array($token[$i + 2]))
            {
                die("invalid");
            }

            $params[$token[$i][1]] = NULL;
            $i+=1;
        }

        if ($token[$i] !== "," && $token[$i] !== ")")
        {
            die("invalid");
        }
    }
    var_dump($params);
}


Please tell me if there are any cons, limitation or bug in this code or any alternatives.

Last annotation in doc comment is ignore, as you can see.

Solution

Focusing on the regex side only....

The use of the UNGREEDY modifier on your pattern, and then internally reversing that, is odd.

$pattern = "/@(\w+?)(.*?)/U";


This can be written simpler, as:

$pattern = "/@(\w+)(.*)/";


The above will work because regex will favour matching the full \w+ before it starts on the .*. If you want to make it explicit (and I would, for the record), you can force a zero-width word-break anchor (\b) in there, and write the pattern as:

$pattern = "/@(\w+)\b(.*)/";

Code Snippets

$pattern = "/@(\w+?)(.*?)/U";
$pattern = "/@(\w+)(.*)/";
$pattern = "/@(\w+)\b(.*)/";

Context

StackExchange Code Review Q#41470, answer score: 4

Revisions (0)

No revisions yet.