PHP to the rescue!! This code will read a BNF and give it back to you in
an easy-to-use associative array. Very handy if I do say so myself. Got
me through the 431 parser in only a few lines of code.  Enjoy!

<?php

// This code is GPLed. Copyleft, Dave Smith, 2003 :-)

$file = file( "my_grammar.txt" );
$grammar = array();
$line_num = read_grammar( 0, $file, $grammar );
print_r( $grammar );
exit;

function read_terminal( $str ) {
        preg_match( "/^([^<]+)<?/", $str, $match );
        return $match[1];
}

function read_nonterminals( $str ) {
        if( $str{0} != '<' ) return false;
        preg_match_all( "/<[^<>]+>/", $str, $match );
        return $match[0];
}

function read_nonterminal( $str ) {
        preg_match( "/^(<[^>]+>)/", $str, $match );
        return $match[1];
}

function read_grammar( $line_num, $file, &$grammar )
{
        // build the grammar
        $grammar = array();
        $count = 0;
        while( null != trim( $line = $file[$line_num] ) ) {
                //echo "$line_num: $line";
                $count++;
                $line = $file[$line_num];
                if( ! trim($line) ) {
                        break;
                } else {
                        $rule = explode( " ::= ", trim($line) );
                        $term = read_terminal( $rule[1] );
                        $next_state =
read_nonterminal(substr($rule[1],strlen($term)));
                        $stack_push = read_nonterminals(substr($rule[1],
strlen($term)+strlen($next_state)));
                        if( ! $next_state && ! $stack_push ) {
                                $next_state = "<POP>";
                                $grammar[ "<POP>" ][ $rule[0] ] = array(
'next_state' => $rule[0], 'stack_push' => NULL );
                        }
                        $grammar[ $rule[0] ][] = array( 'next_state' =>
$next_state,
                                        'stack_push' => $stack_push,
                                        'input' => $term );
                }
                $line_num++;
        }

        return $count;
}

?>

On Sat, 2003-05-31 at 15:46, Lars Olson wrote:
> Anyone know of a tool to parse a large file according to a BNF 
> definition?  I've looked at Parse::RecDescent from CPAN, but it requires 
> you to load the entire file into a string first.  Too slow and too much 
> memory for my purposes.
> 
> (I know there's lex and yacc, but I don't know them very well and it's a 
> fairly simple grammar that I could probably just code up from scratch 
> just as well.)
> 
> 
> ____________________
> BYU Unix Users Group 
> http://uug.byu.edu/
> ___________________________________________________________________
> List Info: http://uug.byu.edu/cgi-bin/mailman/listinfo/uug-list
-- 
David Smith <[EMAIL PROTECTED]>

____________________
BYU Unix Users Group 
http://uug.byu.edu/ 
___________________________________________________________________
List Info: http://uug.byu.edu/cgi-bin/mailman/listinfo/uug-list

Reply via email to