Commit 50aaa78d authored by Per Cederqvist's avatar Per Cederqvist

(reader.parens, reader.rev_parens): New constants.

(reader.__init__): Initialise __parenstack, __errfound and __quoted.
(reader.error, reader.errfound): New methods.
(reader.ungetc, reader.getc_eofok): Handle quoting and parens nesting.
(reader.check_paren_eof): Report unbalanced parens at EOF.
(lexer.__init__): Moved __errfound to the reader class.
(lexer.run): Check for unbalanced parens at EOF.
(lexer.toplevel_reqlink): Ignore.
(lexer.toplevel_reqdlink, lexer.toplevel_linkhere): Ignore, for
	now.  We should check nesting et c of these.
(lexer.toplevel_unmacro): Ignore.
(lexer.error): Moved the implementation to the reader class.  This
	is only a wrapper.
parent 3423f55d
......@@ -7,17 +7,44 @@ class reader_eof(Exception):
pass
class reader:
parens = {'(': ')',
'[': ']',
'{': '}'}
rev_parens = {}
for k, v in parens.items():
rev_parens[v] = k
del v
del k
def __init__(self, file):
self.__filename = file
self.__file = open(file, "r")
self.__line_no = 0
self.__line = []
self.__eof = 0
self.__parenstack = []
self.__errfound = 0
self.__quoted = 0
def filename(self):
return self.__filename
def error(self, line_no, errmsg):
sys.stderr.write("%s:%d:%s\n" % (self.filename(), line_no, errmsg))
self.__errfound = 1
def errfound(self):
return self.__errfound
def ungetc(self, c):
if self.rev_parens.has_key(c):
self.__parenstack.append((self.rev_parens[c], 0))
if self.parens.has_key(c):
assert len(self.__parenstack) > 0
assert self.__parenstack[-1][0] == c
del self.__parenstack[-1]
if c == '@':
self.__quoted = not self.__quoted
self.__line.insert(0, c)
def getc_eofok(self):
......@@ -32,6 +59,23 @@ class reader:
self.__line_no += 1
ret = self.__line[0]
del self.__line[0]
if not self.__quoted:
if ret in '([{':
self.__parenstack.append((ret, self.line_no()))
if ret in '}])':
if len(self.__parenstack) == 0:
self.error(self.line_no(),
"unmatched paren ``%s''" % ret)
else:
if self.__parenstack[-1][0] != self.rev_parens[ret]:
self.error(self.line_no(),
"badly matched parens ``%s'' ``%s''" %
(self.__parenstack[-1][0], ret))
del self.__parenstack[-1]
if ret == '@':
self.__quoted = not self.__quoted
else:
self.__quoted = 0
return ret
def getc(self):
......@@ -43,17 +87,21 @@ class reader:
def line_no(self):
return self.__line_no
def check_paren_eof(self):
for par, line in self.__parenstack:
self.error(line, "unclosed ``%s''" % par)
class lexer:
def __init__(self, file):
self.__reader = reader(file)
self.__errfound = 0
self.__findex = None
def run(self):
while 1:
c = self.__reader.getc_eofok()
if c == None:
return self.__errfound
self.__reader.check_paren_eof()
return self.__reader.errfound()
if c == '@':
self.__toplevel_at()
......@@ -141,6 +189,9 @@ class lexer:
toplevel_asis = ignore
toplevel_item = ignore
toplevel_req = ignore
toplevel_reqlink = ignore
toplevel_reqdlink = ignore # FIXME: check matching @linkhere usage
toplevel_linkhere = ignore # FIXME: check matching @reqdlink usage
toplevel_subsection = ignore
toplevel_itemize = ignore
toplevel_bullet = ignore
......@@ -175,6 +226,7 @@ class lexer:
toplevel_unnumbered = ignore
toplevel_printindex = ignore
toplevel_example = ignore
toplevel_unmacro = ignore
def toplevel_node(self, arg, line_no):
if self.__findex != None:
......@@ -437,9 +489,7 @@ class lexer:
arg = arg + c
def error(self, line_no, errmsg):
sys.stderr.write("%s:%d:%s\n" % (self.__reader.filename(),
line_no, errmsg))
self.__errfound = 1
self.__reader.error(line_no, errmsg)
if __name__ == '__main__':
l = lexer(sys.argv[1])
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment