Skip to content

Instantly share code, notes, and snippets.

@drslump
Last active December 28, 2015 17:29
Show Gist options
  • Save drslump/7536419 to your computer and use it in GitHub Desktop.
Save drslump/7536419 to your computer and use it in GitHub Desktop.
Simple hand coded parser for alarms config
class CfgParser:
def __init__(self, src):
self.src = src
self.idx = 0
def rowcol(self, ofs=None):
ofs = self.idx if ofs is None else ofs
lines = self.src.split('\n')
accum = 0
for ln, line in enumerate(lines):
accum += len(line) + 1
if accum > ofs:
return (ln, accum - ofs)
return (-1, -1)
def char(self):
ch = self.src[self.idx]
self.idx += 1
return ch
def peek(self):
return self.src[self.idx]
def word(self):
word = ''
while True:
ch = self.peek()
if not ch.isalpha() and ch != '_':
break
word += self.char()
return word
def space(self):
space = ''
while True:
ch = self.peek()
if ch == '#': # Skip comments
self.line()
continue
elif ch not in (' ', '\t', '\r', '\n'):
break
space += self.char()
return space
def line(self):
line = ''
while True:
ch = self.char()
if ch == '\n':
break
line += ch
return line
def parse_define(self):
word = self.word()
assert word == 'define', "Expected `define` at " + repr(self.rowcol())
self.space()
word = self.word()
sect = self.parse_section()
return (word, sect)
def parse_section(self):
sect = {}
self.space()
assert self.char() == '{', "Expected `{` at " + repr(self.rowcol())
self.space()
while self.peek() != '}':
self.space()
prop = self.word()
self.space()
line = self.line()
sect[prop] = line
self.char() # Consume ending }
return sect
def parse(self):
results = {'host': [], 'hostgroup': [], 'service': []}
try:
while True:
self.space()
kind, sect = self.parse_define()
if kind not in results:
raise AssertionError('unsupported define "' + kind + '" near ' + repr(self.rowcol()))
results[kind].append(sect)
except AssertionError as ex:
print "ERROR: " + str(ex)
return None
except IndexError:
pass
except Exception as ex:
print 'Exception', ex.__class__, ex
return results
import sys
if len(sys.argv) > 1:
fp = open(sys.argv[1])
code = fp.read()
else:
fp = sys.stdin
code = fp.read()
p = CfgParser(code)
results = p.parse()
from pprint import pprint
pprint(results)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment