diff options
Diffstat (limited to 'ebnf.py')
-rw-r--r-- | ebnf.py | 152 |
1 files changed, 152 insertions, 0 deletions
@@ -0,0 +1,152 @@ +import string + +class EBNF: + IDENT = 0 + LITERAL = 2 + LPAREN = 3 + LBRAK = 4 + LBRACE = 5 + BAR = 6 + EQL = 7 + RPAREN = 8 + RBRAK = 9 + RBRACE = 10 + PERIOD = 11 + OTHER = 12 + + __input__ = None + __char__ = None + __symbol__ = None + __data__ = None + + def __init__(self, input): + self.__input__ = input + self.__get_char__() + + def __get_char__(self): + self.__char__ = self.__input__.read(1) + if self.__char__ == '': + raise EOFError + return self.__char__ + + def __get_sym__(self): + self.__data__ = None + + while self.__char__ in string.whitespace: + self.__get_char__() + + if self.__char__ in string.letters + "_": + self.__symbol__ = self.IDENT + self.__data__ = self.__char__ + while self.__get_char__() in string.letters + "_": + self.__data__ += self.__char__ + return + + elif self.__char__ == '"': + self.__symbol__ = self.LITERAL + self.__data__ = "" + while self.__get_char__() != '"': + self.__data__ += self.__char__ + + elif self.__char__ == '=': + self.__symbol__ = self.EQL + elif self.__char__ == '(': + self.__symbol__ = self.LPAREN + elif self.__char__ == ')': + self.__symbol__ = self.RPAREN + elif self.__char__ == '[': + self.__symbol__ = self.LBRAK + elif self.__char__ == ']': + self.__symbol__ = self.RBRAK + elif self.__char__ == '{': + self.__symbol__ = self.LBRACE + elif self.__char__ == '}': + self.__symbol__ = self.RBRACE + elif self.__char__ == '|': + self.__symbol__ = self.BAR + elif self.__char__ == '.': + self.__symbol__ = self.PERIOD + else: + self.__symbol__ = self.OTHER + + self.__get_char__() + + def __error__(self, num): + pos = self.__input__.tell() + if pos > self.__lastpos__ + 2: + print "ERROR: pos=%d, err=%d, sym=%d" % (pos, num, self.__symbol__) + self.__lastpos__ = pos + + def __expression__(self): + self.__term__() + while self.__symbol__ == self.BAR: + self.__get_sym__() + self.__term__() + + def __term__(self): + self.__factor__() + while self.__symbol__ < self.BAR: + self.__factor__() + + def __factor__(self): + if self.__symbol__ == self.IDENT: + print "record(TO, '%s', 1)" % (self.__data__,) + self.__get_sym__() + elif self.__symbol__ == self.LITERAL: + print "record(T1, '%s', 0)" % (self.__data__,) + self.__get_sym__() + elif self.__symbol__ == self.LPAREN: + self.__get_sym__() + self.__expression__() + if self.__symbol__ == self.RPAREN: + self.__get_sym__() + else: + self.__error__(2) + elif self.__symbol__ == self.LBRAK: + self.__get_sym__() + self.__expression__() + if self.__symbol__ == self.RBRAK: + self.__get_sym__() + else: + self.__error__(3) + elif self.__symbol__ == self.LBRACE: + self.__get_sym__() + self.__expression__() + if self.__symbol__ == self.RBRACE: + self.__get_sym__() + else: + self.__error__(4) + else: + self.__error__(5) + + def __production__(self): + self.__get_sym__() + + if self.__symbol__ == self.EQL: + self.__get_sym__() + else: + self.__error__(7) + + self.__expression__() + + if self.__symbol__ == self.PERIOD: + self.__get_sym__() + else: + self.__error__(8) + + def __syntax__(self): + while self.__symbol__ == self.IDENT: + self.__production__() + + def compile(self): + try: + self.__lastpos__ = 0 + self.__get_sym__() + self.__syntax__() + except EOFError: + return + +if __name__ == '__main__': + import sys + ebnf = EBNF(sys.stdin) + ebnf.compile() |