1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
|
#! /usr/bin/perl -w
use strict;
use 5.010;
use Regexp::Grammars;
use Data::Dumper 'Dumper';
my $grammar = qr{
<Script>
# THIS IS THE MAGIC BIT...
<token: ws>
( \s+
| ^ \# (file \s+ \S+, \s* line \s+ \d+ ) (?{ our $explicit_at = $^N })
)*
<rule: Script>
<[Statement]>* \Z
<rule: Statement>
<Assignment> <where>
| <IfThenElse> <where>
| <Expression> <where>
| <error:>
<token: where>
<matchpos>
<MATCH=(?{ our $explicit_at; $explicit_at || "line $MATCH{matchpos}" })>
<rule: Assignment>
<Variable> [<]- <Expression>
<rule: Expression>
<Product> \+ <Expression>
| <Product>
<rule: Product>
<Value> [*] <Product>
| <Value>
<token: Value>
\d+
| <Variable>
<token: Variable>
(?!if) [a-z]
<rule: IfThenElse>
if <Condition>
then <Statement>
else <Statement>
<rule: Condition>
<Expression> [<] <Expression>
}xms;
do{ local $/; <DATA> } =~ $grammar
or die "Bad script";
warn Dumper \%/
__DATA__
a <- 1
b <- 2
#file foo, line 27
if a<b then
c <- 3
else
#file bar, line 100
c
#file bar, line 200
<- 99
b*c+a
|