58 # FDEL = io.open(FDELNAME, mode='r', buffering=1, encoding="utf-8") |
58 # FDEL = io.open(FDELNAME, mode='r', buffering=1, encoding="utf-8") |
59 # else: |
59 # else: |
60 # FDEL = None |
60 # FDEL = None |
61 |
61 |
62 ################################################################ |
62 ################################################################ |
63 |
|
64 class Parser: |
|
65 |
|
66 COMMENT_RE = re.compile("^; ") |
|
67 NUM_RE = re.compile(u"^# ([1-9][0-9]*)$") |
|
68 PHRASE_START_RE = re.compile(u"^- (.*)") |
|
69 |
|
70 def __init__(self): |
|
71 pass |
|
72 |
|
73 def readline(self): |
|
74 while True: |
|
75 self.line = self.stream.readline() |
|
76 self.eof = len(self.line) == 0 |
|
77 if self.eof: |
|
78 break |
|
79 self.lineno += 1 |
|
80 if self.COMMENT_RE.search(self.line): |
|
81 continue |
|
82 self.line = self.line.strip(' \n\t') |
|
83 if len(self.line) > 0: |
|
84 break |
|
85 |
|
86 def parse(self, stream): |
|
87 self.lineno = 0 |
|
88 self.stream = stream |
|
89 self.dom = dict() |
|
90 self.eof = False |
|
91 try: |
|
92 self.parse_prelude() |
|
93 while not self.eof: |
|
94 self.parse_article() |
|
95 except ParseException as ex: |
|
96 if sys.version_info.major == 2: |
|
97 import traceback |
|
98 traceback.print_exc() |
|
99 raise ParseException(ex.msg, self.lineno, self.line) |
|
100 return self.dom |
|
101 |
|
102 def parse_prelude(self): |
|
103 while True: |
|
104 self.readline() |
|
105 if self.eof: |
|
106 return |
|
107 m = self.NUM_RE.match(self.line) |
|
108 if m: |
|
109 self.num = m.group(1) |
|
110 break |
|
111 |
|
112 def parse_article(self): |
|
113 """Assume we are at ``# NUM`` line.""" |
|
114 num = self.num |
|
115 phrase_buf = [] |
|
116 phrases = [] |
|
117 while True: |
|
118 self.readline() |
|
119 if self.eof: |
|
120 if len(phrase_buf) > 0: |
|
121 phrases.append(" ".join(phrase_buf)) |
|
122 break |
|
123 m = self.NUM_RE.match(self.line) |
|
124 if m: |
|
125 if len(phrase_buf) > 0: |
|
126 phrases.append(" ".join(phrase_buf)) |
|
127 self.num = m.group(1) |
|
128 break |
|
129 m = self.PHRASE_START_RE.match(self.line) |
|
130 if m: |
|
131 if len(phrase_buf) > 0: |
|
132 phrases.append(" ".join(phrase_buf)) |
|
133 phrase_buf = [m.group(1)] |
|
134 else: |
|
135 phrase_buf.append(self.line) |
|
136 if len(phrases) == 0: |
|
137 raise ParseException("""There are no any phrases...""") |
|
138 if num in self.dom: |
|
139 raise ParseException("""Conflicting key: {}...""".format(num)) |
|
140 self.dom[num] = phrases |
|
141 |
63 |
142 FIN = io.open(FINAME, mode='r', buffering=1, encoding="utf-8") |
64 FIN = io.open(FINAME, mode='r', buffering=1, encoding="utf-8") |
143 |
65 |
144 PARSER = Parser() |
66 PARSER = Parser() |
145 try: |
67 try: |