Add at-rules

This commit is contained in:
Max Brunsfeld 2018-10-18 09:59:09 -07:00
parent c3ffccdac1
commit a39aceaa44
6 changed files with 3793 additions and 1720 deletions

View File

@ -1,5 +1,5 @@
========================== ==========================
Functions Function calls
========================== ==========================
a { a {
@ -14,8 +14,26 @@ a {
(block (block
(declaration (declaration
(property_name) (property_name)
(function_value (function_name) (arguments (call_expression (function_name) (arguments
(integer_value) (integer_value)
(integer_value) (integer_value)
(integer_value) (integer_value)
(float_value))))))) (float_value)))))))
============================
Color literals
============================
a {
b: #fafd04;
c: #fafd0401;
}
---
(stylesheet
(rule_set
(selectors (tag_name))
(block
(declaration (property_name) (color_value))
(declaration (property_name) (color_value)))))

View File

@ -65,8 +65,8 @@ a[b] {}
(stylesheet (stylesheet
(rule_set (selectors (attribute_selector (attribute_name))) (block)) (rule_set (selectors (attribute_selector (attribute_name))) (block))
(rule_set (selectors (attribute_selector (attribute_name) (value_name))) (block)) (rule_set (selectors (attribute_selector (attribute_name) (keyword_value))) (block))
(rule_set (selectors (attribute_selector (attribute_name) (value_name))) (block)) (rule_set (selectors (attribute_selector (attribute_name) (keyword_value))) (block))
(rule_set (selectors (attribute_selector (tag_name) (attribute_name))) (block))) (rule_set (selectors (attribute_selector (tag_name) (attribute_name))) (block)))
========================= =========================

77
corpus/statements.txt Normal file
View File

@ -0,0 +1,77 @@
==============================
Import statements
==============================
@import url("fineprint.css") print;
@import url("bluish.css") speech;
@import 'custom.css';
@import url("chrome://communicator/skin/");
@import "common.css" screen;
---
(stylesheet
(import_statement (call_expression (function_name) (arguments (string_value))) (keyword_query))
(import_statement (call_expression (function_name) (arguments (string_value))) (keyword_query))
(import_statement (string_value))
(import_statement (call_expression (function_name) (arguments (string_value))))
(import_statement (string_value) (keyword_query)))
==============================
Media statements
==============================
@media screen and (min-width: 30em) and (orientation: landscape) {}
@media (min-height: 680px), screen and (orientation: portrait) {}
@media not all and (monochrome) {}
---
(stylesheet
(media_statement
(binary_query
(binary_query
(keyword_query)
(feature_query (feature_name) (integer_value (unit))))
(feature_query (feature_name) (keyword_value)))
(block))
(media_statement
(feature_query (feature_name) (integer_value (unit)))
(binary_query (keyword_query) (feature_query (feature_name) (keyword_value)))
(block))
(media_statement
(binary_query (negated_query (keyword_query)) (parenthesized_query (keyword_query)))
(block)))
==============================
Charset statements
==============================
@charset "utf-8";
---
(stylesheet
(charset_statement (string_value)))
==============================
Other at-statements
==============================
@font-face {
font-family: "Open Sans";
src: url("/a") format("woff2"), url("/b/c") format("woff");
}
---
(stylesheet
(at_rule
(at_keyword)
(block
(declaration (property_name) (string_value))
(declaration (property_name)
(call_expression (function_name) (arguments (string_value)))
(call_expression (function_name) (arguments (string_value)))
(call_expression (function_name) (arguments (string_value)))
(call_expression (function_name) (arguments (string_value)))))))

View File

@ -10,16 +10,47 @@ module.exports = grammar({
$._descendant_operator, $._descendant_operator,
], ],
inline: $ => [
$._top_level_item,
$._block_item,
],
rules: { rules: {
stylesheet: $ => repeat(choice( stylesheet: $ => repeat($._top_level_item),
_top_level_item: $ => choice(
$.rule_set, $.rule_set,
$.import_statement, $.import_statement,
)), $.media_statement,
$.charset_statement,
$.at_rule
),
// Statements // Statements
import_statement: $ => seq( import_statement: $ => seq(
'@import' '@import',
$._value,
commaSep($._query),
';'
),
media_statement: $ => seq(
'@media',
commaSep1($._query),
$.block
),
charset_statement: $ => seq(
'@charset',
$._value,
';'
),
at_rule: $ => seq(
$.at_keyword,
commaSep($._query),
choice(';', $.block)
), ),
// Rule sets // Rule sets
@ -31,10 +62,11 @@ module.exports = grammar({
selectors: $ => commaSep1($._selector), selectors: $ => commaSep1($._selector),
block: $ => seq( block: $ => seq('{', repeat($._block_item), '}'),
'{',
repeat(choice($.declaration, $.rule_set)), _block_item: $ => choice(
'}' $.declaration,
$._top_level_item
), ),
// Selectors // Selectors
@ -101,20 +133,67 @@ module.exports = grammar({
declaration: $ => prec(1, seq( declaration: $ => prec(1, seq(
alias($.identifier, $.property_name), alias($.identifier, $.property_name),
':', ':',
repeat1($._value), $._value,
repeat(seq(
optional(','),
$._value
)),
';' ';'
)), )),
// Media queries
_query: $ => choice(
alias($.identifier, $.keyword_query),
$.feature_query,
$.binary_query,
$.negated_query,
$.parenthesized_query
),
feature_query: $ => seq(
'(',
alias($.identifier, $.feature_name),
':',
$._value,
')'
),
parenthesized_query: $ => seq(
'(',
$._query,
')'
),
binary_query: $ => prec.left(seq(
$._query,
choice('and', 'or'),
$._query
)),
negated_query: $ => prec(1, seq(
'not',
$._query
)),
// Property Values // Property Values
_value: $ => choice( _value: $ => choice(
alias($.identifier, $.value_name), alias($.identifier, $.keyword_value),
$.color_value, $.color_value,
$.integer_value, $.integer_value,
$.float_value, $.float_value,
$.function_value $.string_value,
$.call_expression
), ),
color_value: $ => /#[0-9a-fA-F]{3,8}/,
string_value: $ => token(choice(
seq("'", /([^']|\\.)+/, "'"),
seq('"', /([^"]|\\.)+/, '"')
)),
integer_value: $ => seq( integer_value: $ => seq(
token(seq( token(seq(
optional(choice('+', '-')), optional(choice('+', '-')),
@ -138,23 +217,21 @@ module.exports = grammar({
unit: $ => token.immediate(/[a-z]+/), unit: $ => token.immediate(/[a-z]+/),
color_value: $ => /#[0-9a-fA-F]{3,6}/, call_expression: $ => seq(
function_value: $ => seq(
alias($.identifier, $.function_name), alias($.identifier, $.function_name),
$.arguments $.arguments
), ),
arguments: $ => seq( arguments: $ => seq(
'(', token.immediate('('),
commaSep($._value), commaSep($._value),
')' ')'
), ),
property_name: $ => $.identifier,
identifier: $ => /[a-zA-Z-_]+/, identifier: $ => /[a-zA-Z-_]+/,
at_keyword: $ => /@[a-zA-Z-_]+/,
comment: $ => token(choice( comment: $ => token(choice(
seq('//', /.*/), seq('//', /.*/),
seq( seq(

414
src/grammar.json vendored
View File

@ -4,6 +4,11 @@
"stylesheet": { "stylesheet": {
"type": "REPEAT", "type": "REPEAT",
"content": { "content": {
"type": "SYMBOL",
"name": "_top_level_item"
}
},
"_top_level_item": {
"type": "CHOICE", "type": "CHOICE",
"members": [ "members": [
{ {
@ -13,9 +18,20 @@
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "import_statement" "name": "import_statement"
},
{
"type": "SYMBOL",
"name": "media_statement"
},
{
"type": "SYMBOL",
"name": "charset_statement"
},
{
"type": "SYMBOL",
"name": "at_rule"
} }
] ]
}
}, },
"import_statement": { "import_statement": {
"type": "SEQ", "type": "SEQ",
@ -23,6 +39,157 @@
{ {
"type": "STRING", "type": "STRING",
"value": "@import" "value": "@import"
},
{
"type": "SYMBOL",
"name": "_value"
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_query"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_query"
}
]
}
}
]
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": ";"
}
]
},
"media_statement": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "@media"
},
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_query"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_query"
}
]
}
}
]
},
{
"type": "SYMBOL",
"name": "block"
}
]
},
"charset_statement": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "@charset"
},
{
"type": "SYMBOL",
"name": "_value"
},
{
"type": "STRING",
"value": ";"
}
]
},
"at_rule": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "at_keyword"
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_query"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_query"
}
]
}
}
]
},
{
"type": "BLANK"
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ";"
},
{
"type": "SYMBOL",
"name": "block"
}
]
} }
] ]
}, },
@ -74,6 +241,17 @@
{ {
"type": "REPEAT", "type": "REPEAT",
"content": { "content": {
"type": "SYMBOL",
"name": "_block_item"
}
},
{
"type": "STRING",
"value": "}"
}
]
},
"_block_item": {
"type": "CHOICE", "type": "CHOICE",
"members": [ "members": [
{ {
@ -82,14 +260,7 @@
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "rule_set" "name": "_top_level_item"
}
]
}
},
{
"type": "STRING",
"value": "}"
} }
] ]
}, },
@ -425,10 +596,31 @@
"value": ":" "value": ":"
}, },
{ {
"type": "REPEAT1",
"content": {
"type": "SYMBOL", "type": "SYMBOL",
"name": "_value" "name": "_value"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "BLANK"
}
]
},
{
"type": "SYMBOL",
"name": "_value"
}
]
} }
}, },
{ {
@ -438,6 +630,130 @@
] ]
} }
}, },
"_query": {
"type": "CHOICE",
"members": [
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "identifier"
},
"named": true,
"value": "keyword_query"
},
{
"type": "SYMBOL",
"name": "feature_query"
},
{
"type": "SYMBOL",
"name": "binary_query"
},
{
"type": "SYMBOL",
"name": "negated_query"
},
{
"type": "SYMBOL",
"name": "parenthesized_query"
}
]
},
"feature_query": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "("
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "identifier"
},
"named": true,
"value": "feature_name"
},
{
"type": "STRING",
"value": ":"
},
{
"type": "SYMBOL",
"name": "_value"
},
{
"type": "STRING",
"value": ")"
}
]
},
"parenthesized_query": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "("
},
{
"type": "SYMBOL",
"name": "_query"
},
{
"type": "STRING",
"value": ")"
}
]
},
"binary_query": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_query"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "and"
},
{
"type": "STRING",
"value": "or"
}
]
},
{
"type": "SYMBOL",
"name": "_query"
}
]
}
},
"negated_query": {
"type": "PREC",
"value": 1,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "not"
},
{
"type": "SYMBOL",
"name": "_query"
}
]
}
},
"_value": { "_value": {
"type": "CHOICE", "type": "CHOICE",
"members": [ "members": [
@ -448,7 +764,7 @@
"name": "identifier" "name": "identifier"
}, },
"named": true, "named": true,
"value": "value_name" "value": "keyword_value"
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
@ -464,10 +780,60 @@
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "function_value" "name": "string_value"
},
{
"type": "SYMBOL",
"name": "call_expression"
} }
] ]
}, },
"color_value": {
"type": "PATTERN",
"value": "#[0-9a-fA-F]{3,8}"
},
"string_value": {
"type": "TOKEN",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "'"
},
{
"type": "PATTERN",
"value": "([^']|\\\\.)+"
},
{
"type": "STRING",
"value": "'"
}
]
},
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "\""
},
{
"type": "PATTERN",
"value": "([^\"]|\\\\.)+"
},
{
"type": "STRING",
"value": "\""
}
]
}
]
}
},
"integer_value": { "integer_value": {
"type": "SEQ", "type": "SEQ",
"members": [ "members": [
@ -651,11 +1017,7 @@
"value": "[a-z]+" "value": "[a-z]+"
} }
}, },
"color_value": { "call_expression": {
"type": "PATTERN",
"value": "#[0-9a-fA-F]{3,6}"
},
"function_value": {
"type": "SEQ", "type": "SEQ",
"members": [ "members": [
{ {
@ -677,8 +1039,11 @@
"type": "SEQ", "type": "SEQ",
"members": [ "members": [
{ {
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING", "type": "STRING",
"value": "(" "value": "("
}
}, },
{ {
"type": "CHOICE", "type": "CHOICE",
@ -719,14 +1084,14 @@
} }
] ]
}, },
"property_name": {
"type": "SYMBOL",
"name": "identifier"
},
"identifier": { "identifier": {
"type": "PATTERN", "type": "PATTERN",
"value": "[a-zA-Z-_]+" "value": "[a-zA-Z-_]+"
}, },
"at_keyword": {
"type": "PATTERN",
"value": "@[a-zA-Z-_]+"
},
"comment": { "comment": {
"type": "TOKEN", "type": "TOKEN",
"content": { "content": {
@ -783,5 +1148,8 @@
"name": "_descendant_operator" "name": "_descendant_operator"
} }
], ],
"inline": [] "inline": [
"_top_level_item",
"_block_item"
]
} }

4855
src/parser.c vendored

File diff suppressed because it is too large Load Diff