mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
Create a python version of QF's script parser.
It's error handling is bogus, but it works for good input :)
This commit is contained in:
parent
d6a1daaf30
commit
08d7131c1b
1 changed files with 72 additions and 0 deletions
72
tools/io_qfmap/script.py
Normal file
72
tools/io_qfmap/script.py
Normal file
|
@ -0,0 +1,72 @@
|
|||
# vim:ts=4:et
|
||||
|
||||
class Script:
|
||||
def __init__(self, filename, text, single="{}()':"):
|
||||
self.filename = filename
|
||||
self.text = text
|
||||
self.single = single
|
||||
self.pos = 0
|
||||
self.line = 1
|
||||
self.unget = False
|
||||
def tokenAvailable(self, crossline=False):
|
||||
if self.unget:
|
||||
return True
|
||||
while self.pos < len(self.text):
|
||||
while self.text[self.pos].isspace():
|
||||
if self.text[self.pos] == "\n":
|
||||
if not crossline:
|
||||
return False
|
||||
self.line += 1
|
||||
self.pos += 1
|
||||
if self.pos == len(self.text):
|
||||
return False
|
||||
if self.text[self.pos] in ["\x1a", "\x04"]:
|
||||
# end of file characters
|
||||
self.pos += 1
|
||||
continue
|
||||
if self.text[self.pos:self.pos + 2] == "//":
|
||||
while (self.pos < len(self.text)
|
||||
and self.text[self.pos] != "\n"):
|
||||
self.pos += 1
|
||||
if self.pos == len(self.text):
|
||||
return False
|
||||
if not crossline:
|
||||
return False
|
||||
continue
|
||||
return True
|
||||
return False
|
||||
def getToken(self, crossline=False):
|
||||
if self.unget:
|
||||
self.unget = False
|
||||
return self.token
|
||||
if not self.tokenAvailable(crossline):
|
||||
if not crossline:
|
||||
self.error("line is incomplete")
|
||||
return None
|
||||
if self.text[self.pos] == "\"":
|
||||
self.pos += 1
|
||||
start = self.pos
|
||||
if self.text[self.pos] == len(self.text):
|
||||
self.error("EOF inside quoted string")
|
||||
while self.text[self.pos] != "\"":
|
||||
if self.pos == len(self.text):
|
||||
self.error("EOF inside quoted string")
|
||||
return None
|
||||
if self.text[self.pos] == "\n":
|
||||
self.line += 1
|
||||
self.pos += 1
|
||||
self.token = self.text[start:self.pos]
|
||||
self.pos += 1
|
||||
else:
|
||||
start = self.pos
|
||||
if self.text[self.pos] in self.single:
|
||||
self.pos += 1
|
||||
else:
|
||||
while (self.pos < len(self.text)
|
||||
and not self.text[self.pos].isspace()
|
||||
and self.text[self.pos] not in self.single):
|
||||
self.pos += 1
|
||||
self.token = self.text[start:self.pos]
|
||||
return self.token
|
||||
def ungetToken(self):
|
||||
self.unget = True
|
Loading…
Reference in a new issue