summaryrefslogtreecommitdiff
path: root/scss/src/grammar/scss.py
diff options
context:
space:
mode:
Diffstat (limited to 'scss/src/grammar/scss.py')
-rw-r--r--scss/src/grammar/scss.py256
1 files changed, 256 insertions, 0 deletions
diff --git a/scss/src/grammar/scss.py b/scss/src/grammar/scss.py
new file mode 100644
index 0000000..4aa27ee
--- /dev/null
+++ b/scss/src/grammar/scss.py
@@ -0,0 +1,256 @@
+# python yapps2.py grammar.g grammar.py
+
+################################################################################
+## Grammar compiled using Yapps:
+
+import re
+from string import *
+from yappsrt import *
+
+
+class SassExpressionScanner(Scanner):
+ patterns = None
+ _patterns = [
+ ('":"', ':'),
+ ('[ \r\t\n]+', '[ \r\t\n]+'),
+ ('COMMA', ','),
+ ('LPAR', '\\(|\\['),
+ ('RPAR', '\\)|\\]'),
+ ('END', '$'),
+ ('MUL', '[*]'),
+ ('DIV', '/'),
+ ('ADD', '[+]'),
+ ('SUB', '-\\s'),
+ ('SIGN', '-(?![a-zA-Z_])'),
+ ('AND', '(?<![-\\w])and(?![-\\w])'),
+ ('OR', '(?<![-\\w])or(?![-\\w])'),
+ ('NOT', '(?<![-\\w])not(?![-\\w])'),
+ ('NE', '!='),
+ ('INV', '!'),
+ ('EQ', '=='),
+ ('LE', '<='),
+ ('GE', '>='),
+ ('LT', '<'),
+ ('GT', '>'),
+ ('STR', "'[^']*'"),
+ ('QSTR', '"[^"]*"'),
+ ('UNITS', '(?<!\\s)(?:[a-zA-Z]+|%)(?![-\\w])'),
+ ('NUM', '(?:\\d+(?:\\.\\d*)?|\\.\\d+)'),
+ ('COLOR', '#(?:[a-fA-F0-9]{6}|[a-fA-F0-9]{3})(?![a-fA-F0-9])'),
+ ('VAR', '\\$[-a-zA-Z0-9_]+'),
+ ('NAME', '\\$?[-a-zA-Z0-9_]+'),
+ ('FNCT', '[-a-zA-Z_][-a-zA-Z0-9_]*(?=\\()'),
+ ('ID', '!?[-a-zA-Z_][-a-zA-Z0-9_]*'),
+ ('BANG_IMPORTANT', '!important'),
+ ]
+
+ def __init__(self, input=None):
+ if hasattr(self, 'setup_patterns'):
+ self.setup_patterns(self._patterns)
+ elif self.patterns is None:
+ self.__class__.patterns = []
+ for t, p in self._patterns:
+ self.patterns.append((t, re.compile(p)))
+ super(SassExpressionScanner, self).__init__(None, ['[ \r\t\n]+'], input)
+
+
+class SassExpression(Parser):
+ def goal(self):
+ expr_lst = self.expr_lst()
+ END = self._scan('END')
+ return expr_lst
+
+ def expr_lst(self):
+ expr_item = self.expr_item()
+ v = [expr_item]
+ while self._peek(self.expr_lst_rsts) == 'COMMA':
+ COMMA = self._scan('COMMA')
+ expr_item = (None, Literal(Undefined()))
+ if self._peek(self.expr_lst_rsts_) not in self.expr_lst_rsts:
+ expr_item = self.expr_item()
+ v.append(expr_item)
+ return ListLiteral(v) if len(v) > 1 else v[0][1]
+
+ def expr_item(self):
+ NAME = None
+ if self._peek(self.expr_item_rsts) == 'NAME':
+ NAME = self._scan('NAME')
+ self._scan('":"')
+ expr_slst = self.expr_slst()
+ return (NAME, expr_slst)
+
+ def expr_slst(self):
+ or_expr = self.or_expr()
+ v = [(None, or_expr)]
+ while self._peek(self.expr_slst_rsts) not in self.expr_lst_rsts:
+ or_expr = self.or_expr()
+ v.append((None, or_expr))
+ return ListLiteral(v, comma=False) if len(v) > 1 else v[0][1]
+
+ def or_expr(self):
+ and_expr = self.and_expr()
+ v = and_expr
+ while self._peek(self.or_expr_rsts) == 'OR':
+ OR = self._scan('OR')
+ and_expr = self.and_expr()
+ v = AnyOp(v, and_expr)
+ return v
+
+ def and_expr(self):
+ not_expr = self.not_expr()
+ v = not_expr
+ while self._peek(self.and_expr_rsts) == 'AND':
+ AND = self._scan('AND')
+ not_expr = self.not_expr()
+ v = AllOp(v, not_expr)
+ return v
+
+ def not_expr(self):
+ _token_ = self._peek(self.not_expr_rsts)
+ if _token_ != 'NOT':
+ comparison = self.comparison()
+ return comparison
+ else: # == 'NOT'
+ NOT = self._scan('NOT')
+ not_expr = self.not_expr()
+ return NotOp(not_expr)
+
+ def comparison(self):
+ a_expr = self.a_expr()
+ v = a_expr
+ while self._peek(self.comparison_rsts) in self.comparison_chks:
+ _token_ = self._peek(self.comparison_chks)
+ if _token_ == 'LT':
+ LT = self._scan('LT')
+ a_expr = self.a_expr()
+ v = BinaryOp(operator.lt, v, a_expr)
+ elif _token_ == 'GT':
+ GT = self._scan('GT')
+ a_expr = self.a_expr()
+ v = BinaryOp(operator.gt, v, a_expr)
+ elif _token_ == 'LE':
+ LE = self._scan('LE')
+ a_expr = self.a_expr()
+ v = BinaryOp(operator.le, v, a_expr)
+ elif _token_ == 'GE':
+ GE = self._scan('GE')
+ a_expr = self.a_expr()
+ v = BinaryOp(operator.ge, v, a_expr)
+ elif _token_ == 'EQ':
+ EQ = self._scan('EQ')
+ a_expr = self.a_expr()
+ v = BinaryOp(operator.eq, v, a_expr)
+ else: # == 'NE'
+ NE = self._scan('NE')
+ a_expr = self.a_expr()
+ v = BinaryOp(operator.ne, v, a_expr)
+ return v
+
+ def a_expr(self):
+ m_expr = self.m_expr()
+ v = m_expr
+ while self._peek(self.a_expr_rsts) in self.a_expr_chks:
+ _token_ = self._peek(self.a_expr_chks)
+ if _token_ == 'ADD':
+ ADD = self._scan('ADD')
+ m_expr = self.m_expr()
+ v = BinaryOp(operator.add, v, m_expr)
+ else: # == 'SUB'
+ SUB = self._scan('SUB')
+ m_expr = self.m_expr()
+ v = BinaryOp(operator.sub, v, m_expr)
+ return v
+
+ def m_expr(self):
+ u_expr = self.u_expr()
+ v = u_expr
+ while self._peek(self.m_expr_rsts) in self.m_expr_chks:
+ _token_ = self._peek(self.m_expr_chks)
+ if _token_ == 'MUL':
+ MUL = self._scan('MUL')
+ u_expr = self.u_expr()
+ v = BinaryOp(operator.mul, v, u_expr)
+ else: # == 'DIV'
+ DIV = self._scan('DIV')
+ u_expr = self.u_expr()
+ v = BinaryOp(operator.truediv, v, u_expr)
+ return v
+
+ def u_expr(self):
+ _token_ = self._peek(self.u_expr_rsts)
+ if _token_ == 'SIGN':
+ SIGN = self._scan('SIGN')
+ u_expr = self.u_expr()
+ return UnaryOp(operator.neg, u_expr)
+ elif _token_ == 'ADD':
+ ADD = self._scan('ADD')
+ u_expr = self.u_expr()
+ return UnaryOp(operator.pos, u_expr)
+ else: # in self.u_expr_chks
+ atom = self.atom()
+ return atom
+
+ def atom(self):
+ _token_ = self._peek(self.u_expr_chks)
+ if _token_ == 'ID':
+ ID = self._scan('ID')
+ return Literal(parse_bareword(ID))
+ elif _token_ == 'BANG_IMPORTANT':
+ BANG_IMPORTANT = self._scan('BANG_IMPORTANT')
+ return Literal(String(BANG_IMPORTANT, quotes=None))
+ elif _token_ == 'LPAR':
+ LPAR = self._scan('LPAR')
+ expr_lst = ListLiteral()
+ if self._peek(self.atom_rsts) not in self.atom_chks:
+ expr_lst = self.expr_lst()
+ RPAR = self._scan('RPAR')
+ return Parentheses(expr_lst)
+ elif _token_ == 'FNCT':
+ FNCT = self._scan('FNCT')
+ LPAR = self._scan('LPAR')
+ expr_lst = ListLiteral()
+ if self._peek(self.atom_rsts) not in self.atom_chks:
+ expr_lst = self.expr_lst()
+ RPAR = self._scan('RPAR')
+ return CallOp(FNCT, expr_lst)
+ elif _token_ == 'NUM':
+ NUM = self._scan('NUM')
+ UNITS = None
+ if self._peek(self.atom_rsts_) == 'UNITS':
+ UNITS = self._scan('UNITS')
+ return Literal(NumberValue(float(NUM), unit=UNITS))
+ elif _token_ == 'STR':
+ STR = self._scan('STR')
+ return Literal(String(STR[1:-1], quotes="'"))
+ elif _token_ == 'QSTR':
+ QSTR = self._scan('QSTR')
+ return Literal(String(QSTR[1:-1], quotes='"'))
+ elif _token_ == 'COLOR':
+ COLOR = self._scan('COLOR')
+ return Literal(ColorValue(ParserValue(COLOR)))
+ else: # == 'VAR'
+ VAR = self._scan('VAR')
+ return Variable(VAR)
+
+ m_expr_chks = set(['MUL', 'DIV'])
+ comparison_rsts = set(['LPAR', 'QSTR', 'RPAR', 'BANG_IMPORTANT', 'LE', 'COLOR', 'NE', 'LT', 'NUM', 'COMMA', 'GT', 'END', 'SIGN', 'ADD', 'FNCT', 'STR', 'VAR', 'EQ', 'ID', 'AND', 'GE', 'NOT', 'OR'])
+ atom_rsts = set(['LPAR', 'BANG_IMPORTANT', 'END', 'NAME', 'COLOR', 'QSTR', 'SIGN', 'VAR', 'ADD', 'NUM', 'FNCT', 'STR', 'NOT', 'RPAR', 'ID'])
+ u_expr_chks = set(['LPAR', 'COLOR', 'QSTR', 'NUM', 'FNCT', 'STR', 'VAR', 'BANG_IMPORTANT', 'ID'])
+ m_expr_rsts = set(['LPAR', 'SUB', 'QSTR', 'RPAR', 'MUL', 'DIV', 'BANG_IMPORTANT', 'LE', 'COLOR', 'NE', 'LT', 'NUM', 'COMMA', 'GT', 'END', 'SIGN', 'GE', 'FNCT', 'STR', 'VAR', 'EQ', 'ID', 'AND', 'ADD', 'NOT', 'OR'])
+ expr_lst_rsts_ = set(['LPAR', 'BANG_IMPORTANT', 'END', 'NAME', 'COLOR', 'QSTR', 'SIGN', 'VAR', 'ADD', 'NUM', 'COMMA', 'FNCT', 'STR', 'NOT', 'RPAR', 'ID'])
+ a_expr_rsts = set(['LPAR', 'SUB', 'QSTR', 'RPAR', 'BANG_IMPORTANT', 'LE', 'COLOR', 'NE', 'LT', 'NUM', 'COMMA', 'GT', 'END', 'SIGN', 'GE', 'FNCT', 'STR', 'VAR', 'EQ', 'ID', 'AND', 'ADD', 'NOT', 'OR'])
+ or_expr_rsts = set(['LPAR', 'RPAR', 'BANG_IMPORTANT', 'END', 'COLOR', 'QSTR', 'ID', 'VAR', 'ADD', 'NUM', 'COMMA', 'FNCT', 'STR', 'NOT', 'SIGN', 'OR'])
+ u_expr_rsts = set(['LPAR', 'COLOR', 'QSTR', 'SIGN', 'ADD', 'NUM', 'FNCT', 'STR', 'VAR', 'BANG_IMPORTANT', 'ID'])
+ expr_lst_rsts = set(['END', 'COMMA', 'RPAR'])
+ expr_item_rsts = set(['LPAR', 'NAME', 'COLOR', 'QSTR', 'SIGN', 'VAR', 'ADD', 'NUM', 'FNCT', 'STR', 'NOT', 'BANG_IMPORTANT', 'ID'])
+ not_expr_rsts = set(['LPAR', 'COLOR', 'QSTR', 'SIGN', 'VAR', 'ADD', 'NUM', 'FNCT', 'STR', 'NOT', 'BANG_IMPORTANT', 'ID'])
+ atom_rsts_ = set(['LPAR', 'SUB', 'QSTR', 'RPAR', 'VAR', 'MUL', 'DIV', 'BANG_IMPORTANT', 'LE', 'COLOR', 'NE', 'LT', 'NUM', 'COMMA', 'GT', 'END', 'SIGN', 'GE', 'FNCT', 'STR', 'UNITS', 'EQ', 'ID', 'AND', 'ADD', 'NOT', 'OR'])
+ atom_chks = set(['END', 'RPAR'])
+ comparison_chks = set(['GT', 'GE', 'NE', 'LT', 'LE', 'EQ'])
+ a_expr_chks = set(['ADD', 'SUB'])
+ and_expr_rsts = set(['AND', 'LPAR', 'RPAR', 'END', 'COLOR', 'QSTR', 'SIGN', 'VAR', 'ADD', 'NUM', 'COMMA', 'FNCT', 'STR', 'NOT', 'ID', 'BANG_IMPORTANT', 'OR'])
+ expr_slst_rsts = set(['LPAR', 'RPAR', 'END', 'COLOR', 'QSTR', 'SIGN', 'VAR', 'ADD', 'NUM', 'COMMA', 'FNCT', 'STR', 'NOT', 'BANG_IMPORTANT', 'ID'])
+
+
+### Grammar ends.
+################################################################################