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 {
@ -14,8 +14,26 @@ a {
(block
(declaration
(property_name)
(function_value (function_name) (arguments
(call_expression (function_name) (arguments
(integer_value)
(integer_value)
(integer_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
(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) (value_name))) (block))
(rule_set (selectors (attribute_selector (attribute_name) (keyword_value))) (block))
(rule_set (selectors (attribute_selector (attribute_name) (keyword_value))) (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,
],
inline: $ => [
$._top_level_item,
$._block_item,
],
rules: {
stylesheet: $ => repeat(choice(
stylesheet: $ => repeat($._top_level_item),
_top_level_item: $ => choice(
$.rule_set,
$.import_statement,
)),
$.media_statement,
$.charset_statement,
$.at_rule
),
// Statements
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
@ -31,10 +62,11 @@ module.exports = grammar({
selectors: $ => commaSep1($._selector),
block: $ => seq(
'{',
repeat(choice($.declaration, $.rule_set)),
'}'
block: $ => seq('{', repeat($._block_item), '}'),
_block_item: $ => choice(
$.declaration,
$._top_level_item
),
// Selectors
@ -101,20 +133,67 @@ module.exports = grammar({
declaration: $ => prec(1, seq(
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
_value: $ => choice(
alias($.identifier, $.value_name),
alias($.identifier, $.keyword_value),
$.color_value,
$.integer_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(
token(seq(
optional(choice('+', '-')),
@ -138,23 +217,21 @@ module.exports = grammar({
unit: $ => token.immediate(/[a-z]+/),
color_value: $ => /#[0-9a-fA-F]{3,6}/,
function_value: $ => seq(
call_expression: $ => seq(
alias($.identifier, $.function_name),
$.arguments
),
arguments: $ => seq(
'(',
token.immediate('('),
commaSep($._value),
')'
),
property_name: $ => $.identifier,
identifier: $ => /[a-zA-Z-_]+/,
at_keyword: $ => /@[a-zA-Z-_]+/,
comment: $ => token(choice(
seq('//', /.*/),
seq(

414
src/grammar.json vendored
View File

@ -4,6 +4,11 @@
"stylesheet": {
"type": "REPEAT",
"content": {
"type": "SYMBOL",
"name": "_top_level_item"
}
},
"_top_level_item": {
"type": "CHOICE",
"members": [
{
@ -13,9 +18,20 @@
{
"type": "SYMBOL",
"name": "import_statement"
},
{
"type": "SYMBOL",
"name": "media_statement"
},
{
"type": "SYMBOL",
"name": "charset_statement"
},
{
"type": "SYMBOL",
"name": "at_rule"
}
]
}
},
"import_statement": {
"type": "SEQ",
@ -23,6 +39,157 @@
{
"type": "STRING",
"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",
"content": {
"type": "SYMBOL",
"name": "_block_item"
}
},
{
"type": "STRING",
"value": "}"
}
]
},
"_block_item": {
"type": "CHOICE",
"members": [
{
@ -82,14 +260,7 @@
},
{
"type": "SYMBOL",
"name": "rule_set"
}
]
}
},
{
"type": "STRING",
"value": "}"
"name": "_top_level_item"
}
]
},
@ -425,10 +596,31 @@
"value": ":"
},
{
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"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": {
"type": "CHOICE",
"members": [
@ -448,7 +764,7 @@
"name": "identifier"
},
"named": true,
"value": "value_name"
"value": "keyword_value"
},
{
"type": "SYMBOL",
@ -464,10 +780,60 @@
},
{
"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": {
"type": "SEQ",
"members": [
@ -651,11 +1017,7 @@
"value": "[a-z]+"
}
},
"color_value": {
"type": "PATTERN",
"value": "#[0-9a-fA-F]{3,6}"
},
"function_value": {
"call_expression": {
"type": "SEQ",
"members": [
{
@ -677,8 +1039,11 @@
"type": "SEQ",
"members": [
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": "("
}
},
{
"type": "CHOICE",
@ -719,14 +1084,14 @@
}
]
},
"property_name": {
"type": "SYMBOL",
"name": "identifier"
},
"identifier": {
"type": "PATTERN",
"value": "[a-zA-Z-_]+"
},
"at_keyword": {
"type": "PATTERN",
"value": "@[a-zA-Z-_]+"
},
"comment": {
"type": "TOKEN",
"content": {
@ -783,5 +1148,8 @@
"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