# vim: syntax=ruby class Nagios::Parser
token DEFINE NAME STRING PARAM LCURLY RCURLY VALUE RETURN COMMENT INLINECOMMENT
rule decls: decl { return val if val }
| decls decl {
if val[1].nil?
result = val[0]
else
if val[0].nil?
result = val[1]
else
result = [ val[0], val[1] ].flatten
end
end
}
;
decl: object { result = [val] }
| RETURN { result = nil }
| comment
;
comment: COMMENT RETURN { result = nil }
;
object: DEFINE NAME LCURLY RETURN vars RCURLY {
result = Nagios::Base.create(val[1],val[4]) } ;
vars: var
| vars var { val[1].each {|p,v| val[0][p] = v } result = val[0] } ;
var: PARAM VALUE icomment returns { result = {val,val} }
;
returns: RETURN
| returns RETURN ;
icomment: # nothing
| INLINECOMMENT ;
end
—-inner
class ::Nagios::Parser::SyntaxError < RuntimeError; end
def parse(src)
@src = src # state variables @invar = false @inobject = false @done = false @line = 0 @yydebug = true do_parse
end
# The lexer. Very simple. def token
@src.sub!(/\A\n/,'')
if $&
@line += 1
return [ :RETURN, "\n" ]
end
if @done
return nil
end
yytext = String.new
# remove comments from this line
@src.sub!(/\A[ \t]*;.*\n/,"\n")
if $&
return [:INLINECOMMENT, ""]
end
@src.sub!(/\A#.*\n/,"\n")
if $&
return [:COMMENT, ""]
end
@src.sub!(/#.*/,'')
if @src.length == 0
@done = true
return [false, '$']
end
if @invar
@src.sub!(/\A[ \t]+/,'')
@src.sub!(/\A([^;\n]+)(\n|;)/,'\2')
if $1
yytext += $1
end
@invar = false
return [:VALUE, yytext]
else
@src.sub!(/\A[\t ]*(\S+)([\t ]*|$)/,'')
if $1
yytext = $1
case yytext
when 'define'
#puts "got define"
return [:DEFINE, yytext]
when '{'
#puts "got {"
@inobject = true
return [:LCURLY, yytext]
else
unless @inobject
#puts "got type: #{yytext}"
if yytext =~ /\W/
giveback = yytext.dup
giveback.sub!(/^\w+/,'')
#puts "giveback " + giveback
#puts "yytext " + yytext
yytext.sub!(/\W.*$/,'')
#puts "yytext " + yytext
#puts "all [#{giveback} #{yytext} #{orig}]"
@src = giveback + @src
end
return [:NAME, yytext]
else
if yytext == '}'
#puts "got closure: #{yytext}"
@inobject = false
return [:RCURLY, '}']
end
unless @invar
@invar = true
return [:PARAM, $1]
else
end
end
end
end
end
end
def next_token
token
end
def yydebug
1
end
def yywrap
0
end
def on_error(token, value, vstack )
msg = ""
unless value.nil?
msg = "line #{@line}: syntax error at '#{value}'"
else
msg = "line #{@line}: syntax error at '#{token}'"
end
unless @src.size > 0
msg = "line #{@line}: Unexpected end of file"
end
if token == '$end'.intern
puts "okay, this is silly"
else
raise ::Nagios::Parser::SyntaxError, msg
end
end