aboutsummaryrefslogtreecommitdiff
path: root/qls/parser/parser.py
diff options
context:
space:
mode:
authorBicker <bickerkards@tuta.io>2019-05-22 17:45:37 +0200
committerBicker <bickerkards@tuta.io>2019-05-22 17:45:37 +0200
commit25314fd2aed81aa5281bc3d93dbcc7919368ebe1 (patch)
tree1995521ee652e419926de5fced0f2e3b655e70fb /qls/parser/parser.py
Initial commitHEADmaster
Diffstat (limited to 'qls/parser/parser.py')
-rw-r--r--qls/parser/parser.py215
1 files changed, 215 insertions, 0 deletions
diff --git a/qls/parser/parser.py b/qls/parser/parser.py
new file mode 100644
index 0000000..1637e6d
--- /dev/null
+++ b/qls/parser/parser.py
@@ -0,0 +1,215 @@
+from ply.yacc import yacc
+
+from qls.parser.lexer import QLSLexer
+
+
+class QLSParser:
+ def __init__(self):
+ self.__errors = []
+ self.__tokens = QLSLexer.tokens
+ self.__parser = None
+
+ @property
+ def errors(self):
+ return self.__errors
+
+ @property
+ def tokens(self):
+ return self.__tokens
+
+ @property
+ def parser(self):
+ return self.__parser
+
+ def build(self):
+ self.__parser = yacc(module=self)
+
+ def parse(self, data, lexer):
+ return self.parser.parse(data, lexer)
+
+ @staticmethod
+ def p_stylesheet(production):
+ """stylesheet : STYLESHEET IDENTIFIER LEFT_BRACE pages RIGHT_BRACE"""
+ production[0] = ('STYLESHEET', production[2], production[4])
+
+ # Statements
+ @staticmethod
+ def p_pages(production):
+ """pages : page pages
+ | page"""
+ if len(production) == 3:
+ production[0] = [production[1]] + production[2]
+ elif len(production) == 2:
+ production[0] = [production[1]]
+
+ @staticmethod
+ def p_page(production):
+ """page : PAGE IDENTIFIER LEFT_BRACE sections RIGHT_BRACE
+ | PAGE IDENTIFIER LEFT_BRACE sections default RIGHT_BRACE
+ | PAGE IDENTIFIER LEFT_BRACE default RIGHT_BRACE"""
+ if len(production) == 6:
+ production[0] = ('PAGE', production[2], production[4])
+ elif len(production) == 7:
+ production[0] = ('PAGE', production[2], production[4], production[5])
+
+ @staticmethod
+ def p_sections(production):
+ """sections : section sections
+ | section"""
+ if len(production) == 3:
+ production[0] = [production[1]] + production[2]
+ elif len(production) == 2:
+ production[0] = [production[1]]
+
+ @staticmethod
+ def p_statement(production):
+ """statement : section
+ | question"""
+ production[0] = production[1]
+
+ @staticmethod
+ def p_statements(production):
+ """statements : statement statements
+ | statement"""
+ if len(production) == 3:
+ production[0] = [production[1]] + production[2]
+ elif len(production) == 2:
+ production[0] = [production[1]]
+
+ @staticmethod
+ def p_section(production):
+ """section : SECTION STRING_LITERAL LEFT_BRACE statements RIGHT_BRACE
+ | SECTION STRING_LITERAL LEFT_BRACE statements default RIGHT_BRACE
+ | SECTION STRING_LITERAL question
+ | SECTION STRING_LITERAL default"""
+ if len(production) == 4:
+ production[0] = ('SECTION', production[2], [production[3]])
+ elif len(production) == 6:
+ production[0] = ('SECTION', production[2], production[4])
+ elif len(production) == 7:
+ production[0] = ('SECTION', production[2], production[4], production[5])
+
+ @staticmethod
+ def p_question(production):
+ """question : QUESTION IDENTIFIER"""
+ production[0] = ('QUESTION', production[2])
+
+ @staticmethod
+ def p_question_properties(production):
+ """question : QUESTION IDENTIFIER WIDGET widget"""
+ production[0] = ('QUESTION', production[2], production[4])
+
+ @staticmethod
+ def p_default(production):
+ """default : DEFAULT type LEFT_BRACE properties RIGHT_BRACE"""
+ production[0] = ('DEFAULT', production[2], production[4])
+
+ @staticmethod
+ def p_default_widget(production):
+ """default : DEFAULT type WIDGET widget"""
+ production[0] = ('DEFAULT', production[2], production[3])
+
+ # Properties
+ @staticmethod
+ def p_properties(production):
+ """properties : property properties
+ | property"""
+ if len(production) == 3:
+ production[0] = [production[1]] + production[2]
+ elif len(production) == 2:
+ production[0] = [production[1]]
+
+ @staticmethod
+ def p_height(production):
+ """property : HEIGHT COLON INTEGER_LITERAL"""
+ production[0] = ('HEIGHT', production[3])
+
+ @staticmethod
+ def p_width(production):
+ """property : WIDTH COLON INTEGER_LITERAL"""
+ production[0] = ('WIDTH', production[3])
+
+ @staticmethod
+ def p_font(production):
+ """property : FONT COLON STRING_LITERAL"""
+ production[0] = ('FONT', production[3])
+
+ @staticmethod
+ def p_font_size(production):
+ """property : FONT_SIZE COLON INTEGER_LITERAL"""
+ production[0] = ('FONT_SIZE', production[3])
+
+ @staticmethod
+ def p_color(production):
+ """property : COLOR COLON HEX_COLOR"""
+ production[0] = ('COLOR', production[3])
+
+ @staticmethod
+ def p_widget(production):
+ """property : WIDGET widget"""
+ production[0] = ('WIDGET', production[2])
+
+ # Widgets
+ @staticmethod
+ def p_calendar(production):
+ """widget : CALENDAR"""
+ production[0] = 'CALENDAR'
+
+ @staticmethod
+ def p_checkbox(production):
+ """widget : CHECKBOX"""
+ production[0] = 'CHECKBOX'
+
+ @staticmethod
+ def p_line_edit(production):
+ """widget : LINE_EDIT"""
+ production[0] = 'LINE_EDIT'
+
+ @staticmethod
+ def p_spinbox(production):
+ """widget : SPINBOX"""
+ production[0] = 'SPINBOX'
+
+ @staticmethod
+ def p_radio_default(production):
+ """widget : RADIO"""
+ production[0] = 'RADIO'
+
+ @staticmethod
+ def p_radio(production):
+ """widget : RADIO LEFT_BRACKET STRING_LITERAL COMMA STRING_LITERAL RIGHT_BRACKET"""
+ production[0] = ('RADIO', production[3], production[5])
+
+ # Types
+ @staticmethod
+ def p_boolean(production):
+ """type : BOOLEAN"""
+ production[0] = 'BOOLEAN'
+
+ @staticmethod
+ def p_decimal(production):
+ """type : DECIMAL"""
+ production[0] = 'DECIMAL'
+
+ @staticmethod
+ def p_string(production):
+ """type : STRING"""
+ production[0] = 'STRING'
+
+ @staticmethod
+ def p_date(production):
+ """type : DATE"""
+ production[0] = 'DATE'
+
+ @staticmethod
+ def p_money(production):
+ """type : MONEY"""
+ production[0] = 'MONEY'
+
+ @staticmethod
+ def p_integer(production):
+ """type : INTEGER"""
+ production[0] = 'INTEGER'
+
+ def p_error(self, production):
+ self.errors.append('Syntax error at line {}, token={}'.format(production.lineno, production.type))