summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerman M. Bravo <german.mb@deipi.com>2013-08-14 19:32:57 -0500
committerGerman M. Bravo <german.mb@deipi.com>2013-08-16 10:12:12 -0500
commit3069f3e9e2e995cc93857666998d2e5dfd2a84eb (patch)
tree951e8a2eb3b12d3211e2ac931a7139d9ecd49257
parent89005b0119c3753bec59a8aa76f44ae3676f04a7 (diff)
downloadpyscss-3069f3e9e2e995cc93857666998d2e5dfd2a84eb.tar.gz
Cleaned up grammar
-rw-r--r--scss/src/grammar/grammar.g55
-rw-r--r--scss/src/grammar/grammar.py88
2 files changed, 72 insertions, 71 deletions
diff --git a/scss/src/grammar/grammar.g b/scss/src/grammar/grammar.g
index 8798018..20c0a2f 100644
--- a/scss/src/grammar/grammar.g
+++ b/scss/src/grammar/grammar.g
@@ -31,13 +31,32 @@ parser SassExpression:
token COLOR: "#(?:[a-fA-F0-9]{6}|[a-fA-F0-9]{3})(?![a-fA-F0-9])"
token VAR: "\$[-a-zA-Z0-9_]+"
token FNCT: "[-a-zA-Z_][-a-zA-Z0-9_]*(?=\()"
- token ID: "[-a-zA-Z_][-a-zA-Z0-9_]*"
+ token ID: "!?[-a-zA-Z_][-a-zA-Z0-9_]*"
token BANG_IMPORTANT: "!important"
- rule goal: expr_lst {{ v = expr_lst }}
- END {{ return v }}
+ rule goal: expr_lst END {{ return expr_lst }}
- rule expr: and_expr {{ v = and_expr }}
+ rule expr_lst: expr_item {{ v = [expr_item] }}
+ (
+ COMMA [
+ expr_item {{ v.append(expr_item) }}
+ ] {{ else: v.append((None, Literal(Undefined()))) }}
+ )* {{ return ListLiteral(v) if len(v) > 1 else v[0][1] }}
+
+ rule expr_item: {{ var = None }}
+ [
+ VAR [
+ ":" {{ var = VAR }}
+ ] {{ else: self._rewind() }}
+ ]
+ expr_slst {{ return (var, expr_slst) }}
+
+ rule expr_slst: or_expr {{ v = [(None, or_expr)] }}
+ (
+ or_expr {{ v.append((None, or_expr)) }}
+ )* {{ return ListLiteral(v, comma=False) if len(v) > 1 else v[0][1] }}
+
+ rule or_expr: and_expr {{ v = and_expr }}
(
OR and_expr {{ v = AnyOp(v, and_expr) }}
)* {{ return v }}
@@ -78,36 +97,16 @@ parser SassExpression:
rule atom: ID {{ return Literal(parse_bareword(ID)) }}
| BANG_IMPORTANT {{ return Literal(String(BANG_IMPORTANT, quotes=None)) }}
- | LPAR {{ expr_lst = ListLiteral([]) }}
+ | LPAR {{ expr_lst = ListLiteral() }}
[ expr_lst ] RPAR {{ return Parentheses(expr_lst) }}
- | FNCT LPAR {{ expr_lst = ArgspecLiteral([]) }}
+ | FNCT LPAR {{ expr_lst = ListLiteral() }}
[ expr_lst ] RPAR {{ return CallOp(FNCT, expr_lst) }}
- | NUM [
- UNITS {{ return Literal(NumberValue(float(NUM), unit=UNITS.lower())) }}
- ] {{ return Literal(NumberValue(float(NUM))) }}
+ | NUM {{ UNITS = None }}
+ [ UNITS ] {{ return Literal(NumberValue(float(NUM), unit=UNITS)) }}
| STR {{ return Literal(String(STR[1:-1], quotes="'")) }}
| QSTR {{ return Literal(String(QSTR[1:-1], quotes='"')) }}
| COLOR {{ return Literal(ColorValue(ParserValue(COLOR))) }}
| VAR {{ return Variable(VAR) }}
-
- rule expr_lst: expr_item {{ v = [expr_item] }}
- (
- COMMA
- expr_item {{ v.append(expr_item) }}
- )* {{ return ListLiteral(v) if len(v) > 1 else v[0] }}
-
- rule expr_item: {{ var = None }}
- [
- VAR
- [ ":" {{ var = VAR }}
- ] {{ else: self._rewind() }}
- ]
- expr_slst {{ return (var, expr_slst) }}
-
- rule expr_slst: expr {{ v = [expr] }}
- (
- expr {{ v.append(expr) }}
- )* {{ return ListLiteral(v, comma=False) if len(v) > 1 else v[0] }}
%%
### Grammar ends.
################################################################################
diff --git a/scss/src/grammar/grammar.py b/scss/src/grammar/grammar.py
index e89be20..2651d94 100644
--- a/scss/src/grammar/grammar.py
+++ b/scss/src/grammar/grammar.py
@@ -39,7 +39,7 @@ class SassExpressionScanner(Scanner):
('COLOR', '#(?:[a-fA-F0-9]{6}|[a-fA-F0-9]{3})(?![a-fA-F0-9])'),
('VAR', '\\$[-a-zA-Z0-9_]+'),
('FNCT', '[-a-zA-Z_][-a-zA-Z0-9_]*(?=\\()'),
- ('ID', '[-a-zA-Z_][-a-zA-Z0-9_]*'),
+ ('ID', '!?[-a-zA-Z_][-a-zA-Z0-9_]*'),
('BANG_IMPORTANT', '!important'),
]
@@ -56,14 +56,43 @@ class SassExpressionScanner(Scanner):
class SassExpression(Parser):
def goal(self):
expr_lst = self.expr_lst()
- v = expr_lst
END = self._scan('END')
- return v
+ 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')
+ if self._peek(self.expr_lst_rsts_) not in self.expr_lst_rsts:
+ expr_item = self.expr_item()
+ v.append(expr_item)
+ else: v.append((None, Literal(Undefined())))
+ return ListLiteral(v) if len(v) > 1 else v[0][1]
+
+ def expr_item(self):
+ var = None
+ if self._peek(self.expr_item_rsts) == 'VAR':
+ VAR = self._scan('VAR')
+ if self._peek(self.expr_item_rsts_) == '":"':
+ self._scan('":"')
+ var = VAR
+ else: self._rewind()
+ expr_slst = self.expr_slst()
+ return (var, expr_slst)
- def expr(self):
+ 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.expr_rsts) == 'OR':
+ while self._peek(self.or_expr_rsts) == 'OR':
OR = self._scan('OR')
and_expr = self.and_expr()
v = AnyOp(v, and_expr)
@@ -173,7 +202,7 @@ class SassExpression(Parser):
return Literal(String(BANG_IMPORTANT, quotes=None))
elif _token_ == 'LPAR':
LPAR = self._scan('LPAR')
- expr_lst = ListLiteral([])
+ expr_lst = ListLiteral()
if self._peek(self.atom_rsts) not in self.atom_chks:
expr_lst = self.expr_lst()
RPAR = self._scan('RPAR')
@@ -181,17 +210,17 @@ class SassExpression(Parser):
elif _token_ == 'FNCT':
FNCT = self._scan('FNCT')
LPAR = self._scan('LPAR')
- expr_lst = ArgspecLiteral([])
+ 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.lower()))
- return Literal(NumberValue(float(NUM)))
+ return Literal(NumberValue(float(NUM), unit=UNITS))
elif _token_ == 'STR':
STR = self._scan('STR')
return Literal(String(STR[1:-1], quotes="'"))
@@ -205,50 +234,23 @@ class SassExpression(Parser):
VAR = self._scan('VAR')
return Variable(VAR)
- 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 = self.expr_item()
- v.append(expr_item)
- return ListLiteral(v) if len(v) > 1 else v[0]
-
- def expr_item(self):
- var = None
- if self._peek(self.expr_item_rsts) == 'VAR':
- VAR = self._scan('VAR')
- if self._peek(self.expr_item_rsts_) == '":"':
- self._scan('":"')
- var = VAR
- else: self._rewind()
- expr_slst = self.expr_slst()
- return (var, expr_slst)
-
- def expr_slst(self):
- expr = self.expr()
- v = [expr]
- while self._peek(self.expr_slst_rsts) not in self.expr_lst_rsts:
- expr = self.expr()
- v.append(expr)
- return ListLiteral(v, comma=False) if len(v) > 1 else v[0]
-
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', 'COLOR', 'QSTR', 'SIGN', 'NOT', 'ADD', 'NUM', 'FNCT', 'STR', 'VAR', '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(['END', 'COMMA', 'RPAR'])
- and_expr_rsts = set(['AND', 'LPAR', 'RPAR', 'END', 'COLOR', 'QSTR', 'SIGN', 'VAR', 'ADD', 'NUM', 'COMMA', 'FNCT', 'STR', 'NOT', 'ID', 'BANG_IMPORTANT', 'OR'])
+ expr_lst_rsts_ = set(['LPAR', 'BANG_IMPORTANT', 'END', 'COLOR', 'QSTR', 'SIGN', 'NOT', 'ADD', 'NUM', 'COMMA', 'FNCT', 'STR', 'VAR', '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_rsts = set(['LPAR', 'RPAR', 'BANG_IMPORTANT', 'END', 'COLOR', 'QSTR', 'ID', 'VAR', 'ADD', 'NUM', 'COMMA', 'FNCT', 'STR', 'NOT', 'SIGN', 'OR'])
- atom_chks = set(['END', 'RPAR'])
+ expr_lst_rsts = set(['END', 'COMMA', 'RPAR'])
+ expr_item_rsts = set(['LPAR', 'COLOR', 'QSTR', 'SIGN', 'NOT', 'ADD', 'NUM', 'FNCT', 'STR', 'VAR', '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'])
- expr_item_rsts = set(['LPAR', 'COLOR', 'QSTR', 'SIGN', 'NOT', 'ADD', 'NUM', 'FNCT', 'STR', 'VAR', 'BANG_IMPORTANT', 'ID'])
+ atom_chks = set(['END', 'RPAR'])
comparison_chks = set(['GT', 'GE', 'NE', 'LT', 'LE', 'EQ'])
a_expr_chks = set(['ADD', 'SUB'])
- 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'])
+ and_expr_rsts = set(['AND', 'LPAR', 'RPAR', 'END', 'COLOR', 'QSTR', 'SIGN', 'VAR', 'ADD', 'NUM', 'COMMA', 'FNCT', 'STR', 'NOT', 'ID', 'BANG_IMPORTANT', 'OR'])
expr_item_rsts_ = set(['LPAR', 'COLOR', 'QSTR', 'SIGN', 'VAR', 'ADD', 'NUM', '":"', 'STR', 'NOT', 'BANG_IMPORTANT', 'ID', 'FNCT'])
expr_slst_rsts = set(['LPAR', 'RPAR', 'END', 'COLOR', 'QSTR', 'SIGN', 'VAR', 'ADD', 'NUM', 'COMMA', 'FNCT', 'STR', 'NOT', 'BANG_IMPORTANT', 'ID'])