5 # This file is part of LilyPond, the GNU music typesetter.
7 # Copyright (C) 2005 by Carl D. Sorensen <c_sorensen@byu.edu>
9 # LilyPond is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 3 of the License, or
12 # (at your option) any later version.
14 # LilyPond is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
23 # Convert from bison output file parser.output to
25 # Drops all of the state information.
27 # Eliminates the @ variables created when {} is placed
28 # in the middle of a rule
29 # Eliminates all of the c-code stuff
30 # Wraps lines that are longer than 78 characters for improved
33 # to create input file, run
35 # this will create a file parser.output
37 # yyout2grammar.py parser.output your_output_file
43 atre = re.compile('(@\d+):')
45 intro_re = re.compile (r'(.*[:|])\s')
46 keyword_re = re.compile (r'(\S+)\s')
48 # strip extra backslashes that are inserted by the python
49 # string handling routines
50 def strip_backslash(input_string):
51 i=input_string.find(r'"\\')
53 input_string = input_string[:i+1]+input_string[i+2:]
54 i = input_string.find(r'"\\')
57 # write an output line, adjusting to make sure that max_line_length
59 def write_line (output_line, output_file):
62 if len(output_line) > max_line_length:
63 intro = intro_re.match(output_line)
65 output_file.write(intro.group(1)+" ")
66 indent_column = len(intro.group(1))
67 output_line = output_line[indent_column:]
68 keyword = keyword_re.search(output_line)
70 output_file.write(strip_backslash(keyword.group(1))+" \n")
71 output_line = output_line[keyword.end(1):]
72 keyword = keyword_re.search(output_line)
74 output_file.write("".rjust(indent_column + indent_value))
76 output_file.write(strip_backslash(output_line))
82 print "Usage: yyout2grammar.py parser_output_file grammar_file."
85 out_name = sys.argv[2]
87 in_file = open(in_name,'r')
88 out_file= open(out_name, 'w')
91 inline = in_file.readline()
93 ## skip header material from file
94 while inline != '' and not(inline.startswith("Grammar")):
95 inline = in_file.readline()
97 ## process the Grammar lines
99 write_line(inline, out_file)
100 inline = in_file.readline()
101 while inline != '' and not(inline.startswith("Terminals")):
102 i = inline.find("$accept:")
105 inline = in_file.readline()
106 atfound = re.findall(atre,inline)
108 at_items.extend(atfound)
111 inline=in_file.readline()
113 for at_item in at_items:
114 i=inline.find(at_item)
117 inline=inline[:i] + inline[i+len(at_item):]
120 write_line(inline, out_file)
121 inline = in_file.readline()
125 # Write the Terminals header line and the following blank line
126 write_line(inline, out_file)
127 inline = in_file.readline()
128 write_line(inline, out_file)
129 inline = in_file.readline()
130 while inline != '' and not(inline.startswith("Nonterminals")):
131 i=inline.find('"\\\\')
133 inline = inline[:i+1]+inline[i+2:]
134 i = inline.find('"\\\\')
135 index_items.append(inline)
136 inline = in_file.readline()
137 index_items.sort(lambda x,y:cmp(x.lower(),y.lower()))
138 for index_item in index_items:
139 write_line (index_item, out_file)
140 write_line ('\n', out_file)
142 # Write the Nonterminals header and the blank line
143 write_line(inline, out_file)
144 inline = in_file.readline()
145 write_line(inline, out_file)
147 index_item=in_file.readline()
148 inline=in_file.readline()
149 while inline != '' and not(inline.startswith("state")):
150 while inline.startswith(" "):
151 index_item = index_item + inline
152 inline = in_file.readline()
153 if not(index_item.startswith("@")) and \
154 not(index_item.startswith("$accept")):
155 index_items.append(index_item)
157 inline=in_file.readline()
158 index_items.sort(lambda x,y:cmp(x.lower(),y.lower()))
159 for index_item in index_items:
160 write_line (index_item, out_file)