1 |
#!/usr/bin/perl -w |
2 |
|
3 |
# Updates grammer in lscp.xml |
4 |
# |
5 |
# Updates the "Command Syntax" section of Documentation/lscp.xml with current |
6 |
# LSCP grammar definition from network/lscp.y which is the yacc input file |
7 |
# used to automatically generate LinuxSampler's LSCP parser C++ source file |
8 |
# (network/lscpparser.cpp). |
9 |
# |
10 |
# Usage: update_grammar.pl [-v] |
11 |
# |
12 |
# -v verbose output |
13 |
|
14 |
my $YACC_FILE = "../src/network/lscp.y"; |
15 |
my $XML2RFC_FILE = "../Documentation/lscp.xml"; |
16 |
my $ANCHOR_TOKEN_BEGIN = "GRAMMAR_BNF_BEGIN"; |
17 |
my $ANCHOR_TOKEN_END = "GRAMMAR_BNF_END"; |
18 |
|
19 |
my $verbose = 0; |
20 |
if (defined($ARGV[0]) and $ARGV[0] eq "-v") { |
21 |
$verbose = 1; |
22 |
} |
23 |
|
24 |
open(IN, $YACC_FILE) || die "Can't open yacc input file for creating xml2rfc file."; |
25 |
open(OUT, $XML2RFC_FILE) || die "Can't read xml2rfc file."; |
26 |
|
27 |
|
28 |
my @yacc_in = <IN>; |
29 |
my $in_marker_begin = -1; |
30 |
my $in_marker_end = -1; |
31 |
my $i = 0; |
32 |
|
33 |
# scan the yacc input file for the marker lines |
34 |
if ($verbose) { print "Scanning file \"${YACC_FILE}\" ...\n"; } |
35 |
foreach $line (@yacc_in) { |
36 |
if ($line =~ /$ANCHOR_TOKEN_BEGIN/o) { $in_marker_begin = $i; } |
37 |
elsif ($line =~ /$ANCHOR_TOKEN_END/o) { $in_marker_end = $i; } |
38 |
$i++; |
39 |
} |
40 |
if ($in_marker_begin < 0) { |
41 |
die "Did not find ${ANCHOR_TOKEN_BEGIN} token in ${YACC_FILE}, exiting!"; |
42 |
} |
43 |
if ($in_marker_end < 0) { |
44 |
die "Did not find ${ANCHOR_TOKEN_END} token in ${YACC_FILE}, exiting!"; |
45 |
} |
46 |
if ($in_marker_end <= $in_marker_begin) { |
47 |
die "Marker line ${ANCHOR_TOKEN_END} appears before marker line ${ANCHOR_TOKEN_BEGIN}, exiting!"; |
48 |
} |
49 |
if ($verbose) { print "Ok, found ${ANCHOR_TOKEN_BEGIN} in line ${in_marker_begin} and ${ANCHOR_TOKEN_END} in line ${in_marker_end}.\n"; } |
50 |
# delete everything except the grammar lines |
51 |
splice(@yacc_in, $in_marker_end, $#yacc_in - $in_marker_end); |
52 |
splice(@yacc_in, 0, $in_marker_begin + 1); |
53 |
# do the XML transformation |
54 |
$i = 0; |
55 |
foreach $line (@yacc_in) { |
56 |
$_ = $line; |
57 |
# remove C++ code |
58 |
s/\{\p{IsASCII}*\}//g; |
59 |
s/\/\/\p{IsASCII}*$/\r\n/g; |
60 |
s/\{//g; |
61 |
s/\}//g; |
62 |
# place XML tags |
63 |
s!^(\w+)\s*:\s*(\p{IsASCII}*)!<t>$1 =\r\n\t<list>\r\n\t\t<t>$2!; |
64 |
s!^\s+\|\s*(\p{IsASCII}*)!\t\t</t>\r\n\t\t<t>/ $1!; |
65 |
s!^\s*;(\p{IsASCII}*)!\t\t</t>\r\n\t</list>\r\n</t>!; |
66 |
#s/:/<list>/g; |
67 |
# remove space(s) at the end of each line |
68 |
s/\s+$/\r\n/g; |
69 |
$yacc_in[$i] = $_; |
70 |
$i++; |
71 |
} |
72 |
|
73 |
my @xml_in = <OUT>; |
74 |
my $out_marker_begin = -1; |
75 |
my $out_marker_end = -1; |
76 |
$i = 0; |
77 |
|
78 |
# scan the xml2rfc file for the marker lines |
79 |
if ($verbose) { print "Scanning file \"${XML2RFC_FILE}\" ...\n"; } |
80 |
foreach $line (@xml_in) { |
81 |
if ($line =~ /$ANCHOR_TOKEN_BEGIN/o) { $out_marker_begin = $i; } |
82 |
elsif ($line =~ /$ANCHOR_TOKEN_END/o) { $out_marker_end = $i; } |
83 |
$i++; |
84 |
} |
85 |
if ($out_marker_begin < 0) { |
86 |
die "Did not find ${ANCHOR_TOKEN_BEGIN} token in ${XML2RFC_FILE}, exiting!"; |
87 |
} |
88 |
if ($out_marker_end < 0) { |
89 |
die "Did not find ${ANCHOR_TOKEN_END} token in ${XML2RFC_FILE}, exiting!"; |
90 |
} |
91 |
if ($out_marker_end <= $out_marker_begin) { |
92 |
die "Marker line ${ANCHOR_TOKEN_END} appears before marker line ${ANCHOR_TOKEN_BEGIN}, exiting!"; |
93 |
} |
94 |
if ($verbose) { print "Ok, found ${ANCHOR_TOKEN_BEGIN} in line ${out_marker_begin} and ${ANCHOR_TOKEN_END} in line ${out_marker_end}.\n"; } |
95 |
close(OUT); # we reopen in write (clobber) mode |
96 |
|
97 |
# finally replace the area in the output xml file with the new grammar |
98 |
splice(@xml_in, $out_marker_begin + 1, $out_marker_end - $out_marker_begin - 1, @yacc_in); |
99 |
open(OUT, "+>", $XML2RFC_FILE) || die "Can't open xml2rfc file for output"; |
100 |
print OUT @xml_in; |
101 |
close(OUT); |
102 |
close(IN); |
103 |
|
104 |
if ($verbose) { print "Done.\n"; } |
105 |
|
106 |
exit(0); |