Re: converting a BNF to PRD

2004-01-14 Thread Randal L. Schwartz
> "Jim" == Jim Cromie <[EMAIL PROTECTED]> writes:

Jim> Ive been toying recently with PRD, Im new at it, and would like a
Jim> reality check
Jim> Im trying to use it to convert one BNF flavor into a form that can be
Jim> fed into PRD,
Jim> with the resulting parser being used to parse SQL

I converted a random-BNF-like language to Spew (very close to PRD's input)
using PRD for .

See Listing Three, and be sure to read the annotations earlier.

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<[EMAIL PROTECTED]> http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!


Re: converting a BNF to PRD

2004-01-14 Thread Jim Cromie
Orton, Yves wrote:

> Ive been toying recently with PRD, Im new at it, and would like a
> reality check
> Im trying to use it to convert one BNF flavor into a form that can be
> fed into PRD,
> with the resulting parser being used to parse SQL
Itd be a lot easier to help if you provided a link to the BNF you are 
converting.

Yves

Sorry - I should have said this in 1st post.

Theres a URL in the code - Its pretty big, so I thought I shouldnt 
attach it too.

# 1st attempt at a PRD based SQL92::Parser
# to eventually parse these:
# http://www.contrib.andrew.cmu.edu/~shadow/sql/sql2bnf.aug92.txt
# http://www.contrib.andrew.cmu.edu/~shadow/sql/sql3bnf.sep93.txt
-b will load 2nd one by name, if its in PWD. 



RE: converting a BNF to PRD

2004-01-14 Thread Orton, Yves
> Ive been toying recently with PRD, Im new at it, and would like a 
> reality check
> Im trying to use it to convert one BNF flavor into a form that can be 
> fed into PRD,
> with the resulting parser being used to parse SQL

Itd be a lot easier to help if you provided a link to the BNF you are
converting.

Yves


converting a BNF to PRD

2004-01-14 Thread Jim Cromie
Hi folks,

Ive been toying recently with PRD, Im new at it, and would like a 
reality check
Im trying to use it to convert one BNF flavor into a form that can be 
fed into PRD,
with the resulting parser being used to parse SQL

This 2 stage approach seems appropriate cuz; the bnf file is ~3K,
and I dont want to convert it manually, and potentially have to maintain it.
It also seems like a relatively small conversion compared to the 2nd 
stage -
I hope to gain enough competence in 1st stage that the 2nd begins to 
look more practical.
Finally, Id like to think that this BNF can then be supplemented
with vendor specific subclasses,

I also wonder if this might be generally useful/instructive enough to go 
in the
distributions demo/ subdir

what Ive written so far handles these grammar items well enough to start 
with,
but Ive yet to devise the set of actions that will produce the PRD version.
That will probably yield to some effort -

 ::=
 
   | 
 ::=
 A | B | C | D | E | F | G | H | I | J | K | L | M | N | O
   | P | Q | R | S | T | U | V | W | X | Y | Z
 ::=
 a | b | c | d | e | f | g | h | i | j | k | l | m | n | o
   | p | q | r | s | t | u | v | w | x | y | z


Im not clear on the meaning and/or handling of these constructs in the BNF

   looks like a required alternation.  ... repeated one or more times.
::= {  |  |  }...
I think this translates to following, but Im slightly concerned that
the form of the rules has changed, and the conversion is not so simple.
If theres a way to keep a 1/1 correspondence of tthe superficial structure,
then it would keep the 1st stage simple.
   separators : separator(s)
   separator : comment | space | newline
this looks like optional, repeating,

 ::=
[ ... ] 
translating to

   simple_comment : simple_comment_introducer  comment_char(s)? newline

I dont know what to make of this

 ::= !! (See the Syntax Rules.)

This looks like a syntax error - are there other interpreteations ?
 ::=
 
  [  ]   ]




#!/usr/local/bin/perl -w

# 1st attempt at a PRD based SQL92::Parser
# to eventually parse these:
# http://www.contrib.andrew.cmu.edu/~shadow/sql/sql2bnf.aug92.txt
# http://www.contrib.andrew.cmu.edu/~shadow/sql/sql3bnf.sep93.txt

my $dd;
use Data::Dumper::EasyOO (init => \$dd, autoprint => 1, indent => 1);

use Parse::RecDescent;
use Getopt::Std;

$bnffile = 'sql2bnf.aug92.txt';
$bnffile = 'sql3bnf.sep93.txt';

my $sqlgrammar;
my $samplegrammar = q{

This is a cut-paste from one of above files.
It illustrates the bnf syntax used there, which must be adapted
before feeding to P::RD

 ::=
  
| 
| 

 ::=
  
| 

 ::=
  A | B | C | D | E | F | G | H | I | J | K | L | M | N | O
| P | Q | R | S | T | U | V | W | X | Y | Z

 ::=
  a | b | c | d | e | f | g | h | i | j | k | l | m | n | o
| p | q | r | s | t | u | v | w | x | y | z

 ::=
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

};

getopts('bvthaTm', my $opt={}) or die
qq{
b : load sql-bnf
v : verbose - echos the grammar file
t : turn on trace
h : turn on hints
a : autoaction
T : autoTree   
m : print dump of metaparser
};


if ($opt->{b}) {
local $/ = undef;
open ($fh, $bnffile) or die "cant open file: $bnffile: $!\n";
$sqlgrammar = <$fh>;
} else {
$sqlgrammar = $samplegrammar;
}

# alter the grammar syntax used in bnf-file.  Do this at load time,
# rather than hacking the file by hand, and maintaining it forever..

# 1st step is to comment-ize the leading text.  Doing this might be
# simple in PRD (tips welcome), but plain perl works, and needs no
# magic/wizardry.

my $prologue;
if ($sqlgrammar =~ s/^(.+?\n\s){v};

# now try use PRD to morph the grammar syntax used in the bnf file,
# rather than hack at it mercilessly with regexs.

$::RD_TRACE = 1   if $opt->{t};
$::RD_HINT = 1if $opt->{h};

$::RD_AUTOACTION = q/{ bless \%item, $item[0] }/   if $opt->{a};

my $metagrammar = q{
# metagrammar, shamelessly adapted from PRD pod

grammar: ruledefs(s)

ruledefs :
identifier  isdefined  production
#{ "$item{identifier}  $item{isdefined}  $item{production}" }

isdefined  :
/::=\s*/{ ':' }

identifier :
/<(\w+(\s+\w+)*)>/i # 
{ $_ = $1; s/\s+/_/g; $_ }  # strip <>, chg \s+ to '_'

production :
subrule(s /\|/)
| altitems
| item(s)

altitems :
item(s /\|/)

item :
subrule #args(?)# match another rule
| altterms
| bareword  # match the next input

subrule :
identifier(s /\|/)  # the name of the rule

#term   : /(.*)\n\n/{ "qr/$1/x" }

altterms :
bareword(s /\|/)
{ ::crunchregex($item{'bareword(s)'}) }
 
bareword   : /(\w+)/ { "$1" }
};

sub