File indexing completed on 2024-07-14 15:05:09

0001 # -*- coding: utf-8 -*-
0002 #     Copyright 2014 Simon Edwards <simon@simonzone.com>
0003 #
0004 # This program is free software; you can redistribute it and/or modify
0005 # it under the terms of the GNU General Public License as published by
0006 # the Free Software Foundation; either version 2 of the License, or
0007 # (at your option) any later version.
0008 #
0009 # This program is distributed in the hope that it will be useful,
0010 # but WITHOUT ANY WARRANTY; without even the implied warranty of
0011 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012 # GNU General Public License for more details.
0013 #
0014 # You should have received a copy of the GNU General Public License
0015 # along with this program; if not, write to the
0016 # Free Software Foundation, Inc.,
0017 # 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
0018 
0019 import kbindinggenerator.cmakelexer as cmakelexer
0020 import ply.yacc as yacc
0021 
0022 class CMakeThing(object):
0023     def isString(self):
0024         return False
0025     def isSymbol(self):
0026         return False
0027     def value(self):
0028         return self._value
0029 
0030 class CMakeString(CMakeThing):
0031     def __init__(self, value):
0032         self._value = value
0033     def isString(self):
0034         return True
0035     def __eq__(self, other):
0036         return isinstance(other, CMakeString) and other._value == self._value
0037     def __repr__(self):
0038         return 'CMakeString("{0}")'.format(self._value)
0039 
0040 class CMakeSymbol(CMakeThing):
0041     def __init__(self, value):
0042         self._value = value
0043     def isSymbol(self):
0044         return True
0045     def __eq__(self, other):
0046         return isinstance(other, CMakeSymbol) and other._value == self._value
0047     def __repr__(self):
0048         return 'CMakeSymbol("{0}")'.format(self._value)
0049 
0050 class CMakeCommand(object):
0051     def __init__(self, command, arguments):
0052         self._command = command
0053         self._arguments = arguments
0054     def command(self):
0055         return self._command
0056     def arguments(self):
0057         return self._arguments
0058     def __eq__(self, other):
0059         return isinstance(other, CMakeCommand) and other._command == self._command and \
0060             other._arguments == self._arguments
0061     def __repr__(self):
0062         return "CMakeCommand({0}, {1})".format(self._command, repr(self._arguments))
0063 
0064 class CMakeParser(object):
0065 
0066     def __init__(self):
0067         self.tokens = cmakelexer.tokens
0068         yacc.yacc (module = self, tabmodule = "cmakeParserTab")
0069         self._parse = yacc.parse
0070 
0071         self.values = {}
0072 
0073     def parse(self, s, filename=None, debug=0):
0074         self.lexer = cmakelexer.CMakeLexer(filename)
0075         self.lexer.input(s)
0076         self.result = None
0077         self.filename = filename
0078         self._parse(debug = debug, lexer = self.lexer)
0079         return self.result
0080 
0081     def p_cmake_file(self, p):
0082         """cmake_file : statement_list"""
0083         p[0] = p[1]
0084         self.result = p[0]
0085 
0086     def p_statement_list1(self, p):
0087         """statement_list : statement"""
0088         if p[1] is not None:
0089             p[0] = [p[1]]
0090         else:
0091             p[0] = []
0092 
0093     def p_statement_list2(self, p):
0094         """statement_list : statement_list statement"""
0095         if p[2] is not None:
0096             p[0] = p[1] + [p[2]]
0097         else:
0098             p[0] = p[1]
0099 
0100     def p_statement1(self, p):
0101         """statement : SYMBOL LPAREN argument_list RPAREN"""
0102         p[0] = CMakeCommand(p[1], p[3])
0103 
0104     def p_statement2(self, p):
0105         """statement : COMMENT"""
0106         p[0] = None
0107 
0108     def p_statement3(self, p):
0109         """statement : SYMBOL LPAREN RPAREN"""
0110         p[0] = CMakeCommand(p[1], [])
0111 
0112     def p_argument_list(self, p):
0113         """argument_list : argument
0114                          | argument_list argument"""
0115         if len(p) == 2:
0116             p[0] = p[1]
0117         else:
0118             p[0] = p[1] + p[2]
0119 
0120     def p_argument1(self, p):
0121         """argument : SYMBOL"""
0122         p[0] = [CMakeSymbol(p[1])]
0123 
0124     def p_argument2(self, p):
0125         """argument : STRING"""
0126         p[0] = [CMakeString(p[1])]
0127 
0128     def p_argument3(self, p):
0129         """argument : COMMENT"""
0130         p[0] = []
0131 
0132     def p_argument4(self, p):
0133         """argument : LPAREN argument_list RPAREN"""
0134         p[0] = [CMakeSymbol("(")] + p[2] + [CMakeSymbol(")")]
0135 
0136     def p_error(self, p):
0137         if self.filename is None:
0138             print("Syntax error at line %d, '%s'" % (self.lexer.lineno, p.value,))
0139         else:
0140             print("Syntax error at line %d, '%s' in file %s" % (self.lexer.lineno, p.value, self.filename))