source: trunk/tools/writing_editor/scripts/parser.py @ 280

Revision 280, 4.4 KB checked in by bretzel_parpg, 10 years ago (diff)

Patch by Bretzel.

  • Wrote a parser for the new syntax I developed (I will post about this at the forums in the Dialog System Implementation thread)
  • Started to add a dialogue map, which will show you the flow of the dialogue
  • Overrode the resize event in the application so that it will also resize the editor and dialog map
Line 
1#!/usr/bin/python
2
3#   This file is part of PARPG.
4
5#   PARPG is free software: you can redistribute it and/or modify
6#   it under the terms of the GNU General Public License as published by
7#   the Free Software Foundation, either version 3 of the License, or
8#   (at your option) any later version.
9
10#   PARPG is distributed in the hope that it will be useful,
11#   but WITHOUT ANY WARRANTY; without even the implied warranty of
12#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13#   GNU General Public License for more details.
14
15#   You should have received a copy of the GNU General Public License
16#   along with PARPG.  If not, see <http://www.gnu.org/licenses/>.
17
18from PyQt4 import QtGui, QtCore
19
20# goto_table stores label's so you can jump back to them
21# they are stored in the format: {label (string): paragraph number (int, starts at 0)}
22goto_table = {}
23
24class ConversationNode(object):
25    """
26    The class for every node in the conversation tree
27    """
28    def __init__(self, label="", text="", type_="", options=[]):
29        """
30        Initialize the node
31        @type label: string
32        @param label: the label for the node
33        @type text: string
34        @param text: the text for the node
35        @type type_: string
36        @param type_: the type of node, either 'text' or 'option'
37        @type options: list
38        @param options: a list of all the option nodes
39        @return: None
40        """
41        self.label = label
42        self.text = text
43        self.type_ = type_
44        self.options = options
45
46
47def parse(text):
48    """
49    Parse the text and create the tree structure from it
50    @type text: string
51    @param text: the text to parse
52    @return: the root node
53    """
54    text = str(text).strip()
55
56    if (text == ""):
57        # if there is no text return an empty node
58        return ConversationNode()
59
60    # split the text into paragraphs
61    paras = []
62    for line in text.split('\n'):
63        line = line.strip()
64        if line != "":
65            paras.append(line) 
66           
67    # if there is a label make sure to have it in the same paragraph as it's text
68    for para in paras:
69        if para.startswith("LABEL"):
70            para_spot = paras.index(para)
71            next_para = paras[para_spot+1]
72            new_para = para + '\n' + next_para
73
74            paras.remove(para)
75            paras.remove(next_para)
76            paras.insert(para_spot, new_para)
77
78    # recursively parse the text and get the root node and end
79    root, end = _parse(paras, 0, len(paras)-1)
80   
81    # if the end is not the end of the paragraphs, then throw a syntax error
82    if (end != len(paras)):
83        print "syntax error 1"
84
85    # else return the root node
86    else:
87        return root
88
89
90def _parse(paras, start, end):
91    """
92    Recursively parse the text
93    @type paras: list
94    @param paras: a list of the paragraphs in the text
95    @type start: int
96    @param start: the start of the text
97    @type end: int
98    @param end: the end of the text
99    @return: the root node and end of text
100    """
101    # create a new node
102    node = ConversationNode()
103
104    # check for a label and extract it if its there
105    if (paras[0].startswith("LABEL")):
106        label_text = paras[0].split('\n')[0][6:]
107        node.label = label_text
108        goto_table[label_text] = 0
109        paras[0] = paras[0].split('\n')[1]
110
111    for i in xrange(start, end):
112        # if the paragraph is an option, break the loop
113        if (paras[i].startswith("OPTION")):
114            break
115
116        # if the paragraph is an endoption, exit the function and return the node and the end point
117        elif (paras[i].startswith("ENDOPTION")):
118            return node, i
119
120        # else parse the text normally
121        else:
122            node.type = 'text'
123            node.text = paras[i]
124           
125    # while not at the end of the text
126    while i < end:
127        # if the paragraph is an option, start the recursive parsing and append the option to the root node
128        if (paras[i].startswith("OPTION")):
129            txt = paras[i][7:]
130            child, i = _parse(paras, i+1, end)
131            child.type_ = 'option'
132            child.text = txt
133            node.options.append(child)
134           
135        # if the paragraph is an endoption, it is a syntax error
136        elif (paras[i].startswith("ENDOPTION")):
137            print "syntax error 2"
138
139        # move to the next paragraph
140        i += 1
141
142    return node, i
Note: See TracBrowser for help on using the repository browser.