Hmmm... odd I wrote a version of this last night but it would appear
that I failed to post it to the forum, doh! so here it goes again. If
it did get out and this is a duplicate then please accept my apologies
for the waste of bandwidth.
I am writing a recursive descent parser to parse a configuration file
that consists of nested 'Sections' which all look like this:
[<section type> <possibly optional name>] {
<item>
<item>
.
.
}
where <item> may be another section.
I wrote a clase Section to parse the basic structure. Section.initialise
calls method specificItems to parse non section items (see below). For
each type of section I have an anonymous class tied to a Class variable
-- I have included one such class below. I had to make the classes
anonymous because I needed to include references to the classes in a
data structure (see subSections ) which tells the parser which section
types are valid in this section and what to do with them.
[ aside: someone asked why I wanted reference to scalar variable in my
previous post -- this is why. I needed to have a refernce to a variable
in that structure into which I could store the parsed class]
Now to the problem: As you see I have defined a bunch of accessor
methods using attr_reader and attr_writer, but these don't work ( I get
an undefined method error ). Adding the accessor methods explicitly
works fine. Odd!
I'm not sure if this is a bug, a feature or simply some lack in my
understanding of how things should work.
Any ideas?
Also this is my first real OO Ruby program and I would appreciate
comments -- it is too large (currently 1000 lines) to post here but if
anyone would be willing to have a look at it I'd be happy to email it to
them. My email is r.fulton@auckland.ac.nz.
I have run into various problems in this project and have managed to
solve all of them but I am far from confident that my solution was the
best way of doing it. The use of anonymous classes is one example. I
wrote a generic text parser for this project and because Ruby does not
support multiple inheiritance I ended up passing an instance of the
parser as a parameter to all the methods -- I figured that since the
parser needed to maintain state that I could not make it a mixin...
Cheers, Russell
@@hostService = Class.new( Section ) {
attr_reader = :services, :converted, :actions, :patterns,
:realTime,
:periodic, :files
attr_writer = :converted
def initialize( head, parser )
@services = []
@actions = []
@patterns = []
@realTime = []
@periodic = []
@files = []
@converted = false
super( head, parser )
end
# accessor methods --- since the shorthand way did not work
def actions
@actions
end
[ boring repeditive stuff snipped ]
def converted=(value)
@converted = value
end
# this handles the non section items in the section
def specificItem( firstToken, parser )
case firstToken
when 'service'
if token = parser.expect(/^(\w+)/, "service name") then
@services.push( token )
else
@errors = true
parser.restofLine # ignore the rest of the line
end
else
@errors = true
parser.error( "#{firstToken} not valid in host section" )
parser.restofLine # ignore the rest of the line
end
end
# defines which sections may be nested within this section
# Key is the section type the vailue is [ <name required>,
# class to parse section and where to store the result ]
def subSections( kind )
{'actions' => [nil, @@actionList, @actions ],
'files' => [nil, @@commaList, @files],
'patterns' => [nil, @@patternList, @patterns],
'realtime' => [nil, @@matchList, @realTime],
'periodic' => [nil, @@matchList, @periodic]
}[kind]
end
} # end of hostSection
···
--
Posted via http://www.ruby-forum.com/.