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

Revision 251, 5.3 KB checked in by bretzel_parpg, 10 years ago (diff)

Started on putting options in the 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
18import re
19from lib.pyparsing import *
20from PyQt4 import QtGui, QtCore
21
22class Parser():
23    """
24    The parser
25    """
26    def __init__(self, widget, result_function):
27        """
28        Initialize the parser
29        @type document: QtGui.QTextEdit
30        @param document: The QTextEdit
31        @type result_function: function
32        @param result_function: the function that handles the results
33        @return: None
34        """
35        self.widget = widget
36        self.resultFunction = result_function
37        self.makeFunctions()
38        self.funcs = ["SCRIPTNAME", "NPC", "CALLSECTION", "ENDSECTION", "SECTION", 
39                      "SCRIPTNAME", "ENDOPTION", "OPTION", "PLAYSOUND", 
40                      "SAY", "ATTACK", "RETURN", "ELIF", "IF", "ELSE", "PC", "."]
41
42        self.func_by_name = {"NPC":self.npc, "PC":self.pc, "CALLSECTION":self.callsection,
43                             "ENDSECTION":self.endsection, "SECTION": self.section,
44                             "SCRIPTNAME":self.scriptname, "ENDOPTION":self.endoption,
45                             "OPTION":self.option, "PLAYSOUND":self.playsound,
46                             "SAY":self.say, "ATTACK":self.attack, "RETURN":self.return_,
47                             "ELIF":self.elif_, "IF":self.if_, "ELSE":self.else_,
48                             ".":self.option_item}
49
50
51    def makeFunctions(self):
52        """
53        Setup all the matching functions
54        @return: None
55        """
56        self.text = Word(alphanums)
57        self.nums = Word(nums)
58        self.period = Literal(".")
59        self.space = Literal(" ")
60        self.colon = Literal(":")
61        self.quote = Literal("\"")
62
63        self.npc = Combine(Word("NPC") + self.space + self.text)
64        self.pc = Word("PC")
65        self.section = Combine(Word("SECTION") + self.space + self.text)
66        self.endsection = Word("ENDSECTION")
67        self.callsection = Combine(Word("CALLSECTION") + self.space + self.text)
68        self.scriptname = Combine(Word("SCRIPTNAME") + self.space + self.text)
69        self.option = Combine(Word("OPTION") + self.space + self.text)
70        self.option_item = Combine(self.nums + Optional(self.space) + self.period + Optional(self.space) + self.text)
71        self.endoption = Combine(Word("ENDOPTION") + self.space + self.text)
72        self.playsound = Combine(Word("PLAYSOUND") + self.space + self.quote + self.text + self.quote)
73        self.say = Combine(self.text + self.space + Word("SAY") + self.space + self.quote
74                           + self.text + self.quote)
75        self.attack = Combine(self.text + self.space + Word("ATTACK") + self.space + self.text)
76        self.return_ = Combine(Word("RETURN") + self.space + self.text)
77        self.if_ = Combine(Word("IF") + self.space + self.text + self.colon)
78        self.elif_ = Combine(Word("ELIF") + self.space + self.text + self.colon)
79        self.else_ = Combine(Word("ELSE") + self.colon)
80
81       
82    def findType(self, string):
83        """
84        Find the type of command that is in the string given
85        @type string: string
86        @param string: the string to find the type of
87        @return: the type
88        """
89        type_ = None
90        for func in self.funcs:
91            regex = re.compile(func + "{0,1}")
92            if (regex.search(str(string)) != None):
93                type_ = func
94                break
95
96        return type_
97
98    def parse(self):
99        """
100        Parse the text
101        @return: the parsed text
102        """       
103        doc = self.widget.document().toPlainText()
104        if (doc == ""):
105            return
106
107        for line in doc.split('\n'):
108            if (line == ""):
109                continue
110
111            line_type = self.findType(line)
112            try:
113                command = self.func_by_name[line_type]
114            except KeyError, e:
115                self.createErrorBox(e)
116                return
117
118            parse = command.scanString(line)
119            for result in parse:
120                self.resultFunction(result[0][0], line_type)
121
122
123    def createErrorBox(self, error):
124        """
125        Create an error box saying that the text couldn't be parsed
126        @type error: KeyError
127        @param error: The error that was generated
128        @return: None
129        """
130        msg_box = QtGui.QMessageBox()
131        msg_box.setText("Error while parsing")
132        msg_box.setInformativeText("Could not find the type \"%s\" in self.func_by_name" % str(error))
133        msg_box.setStandardButtons(QtGui.QMessageBox.Ok)
134        msg_box.setWindowTitle("Error")
135        msg_box.setWindowIcon(QtGui.QIcon("data/images/error.png"))
136       
137        ret = msg_box.exec_()
138        if (ret == QtGui.QMessageBox.Ok):
139            msg_box.close()
Note: See TracBrowser for help on using the repository browser.