291 lines
6.4 KiB
Plaintext
291 lines
6.4 KiB
Plaintext
@precedence {
|
|
attribute @left,
|
|
structure @left,
|
|
call,
|
|
valueCompareOp,
|
|
valueOp @left,
|
|
layerName
|
|
}
|
|
|
|
@skip { whitespace | Comment }
|
|
|
|
@top StyleSheet { item* }
|
|
|
|
@top Styles { blockContent }
|
|
|
|
item {
|
|
RuleSet |
|
|
ImportStatement |
|
|
MediaStatement |
|
|
CharsetStatement |
|
|
NamespaceStatement |
|
|
KeyframesStatement |
|
|
SupportsStatement |
|
|
ScopeStatement |
|
|
FontFeatureStatement |
|
|
AtRule
|
|
}
|
|
|
|
RuleSet {
|
|
selector ("," selector)* Block
|
|
}
|
|
|
|
ImportStatement {
|
|
atKw<"import">
|
|
value
|
|
Layer {
|
|
queryCalleeKw<"layer"> (!layerName "(" LayerName ("." LayerName)* ")")? |
|
|
queryKw<"layer">
|
|
}?
|
|
commaSep<query> ";"
|
|
}
|
|
|
|
LayerName { identifier }
|
|
|
|
MediaStatement {
|
|
atKw<"media"> commaSep<query> Block
|
|
}
|
|
|
|
CharsetStatement {
|
|
atKw<"charset"> value ";"
|
|
}
|
|
|
|
NamespaceStatement {
|
|
atKw<"namespace">
|
|
NamespaceName { identifier }?
|
|
(StringLiteral | CallLiteral) ";"
|
|
}
|
|
|
|
KeyframesStatement {
|
|
atKw<"keyframes">
|
|
KeyframeName { identifier | StringLiteral }
|
|
KeyframeList
|
|
}
|
|
|
|
KeyframeSelector {
|
|
KeyframeRangeName { identifier } NumberLiteral? |
|
|
NumberLiteral
|
|
}
|
|
|
|
KeyframeList {
|
|
"{" (KeyframeSelector ("," KeyframeSelector)* Block)* "}"
|
|
}
|
|
|
|
SupportsStatement {
|
|
atKw<"supports"> query Block
|
|
}
|
|
|
|
ScopeStatement {
|
|
atKw<"scope">
|
|
ParenthesizedSelector?
|
|
(@extend[@name=to]<identifier, "to"> ParenthesizedSelector)?
|
|
Block
|
|
}
|
|
|
|
FontFeatureStatement {
|
|
atKw<"font-feature-values">
|
|
FontName { identifier+ }
|
|
Block
|
|
}
|
|
|
|
AtRule { AtKeyword (query (","? query)*)? (";" | Block) }
|
|
|
|
Block[@dynamicPrecedence=1] { "{" blockContent "}" }
|
|
|
|
blockContent { ~item item* (Declaration (";" ~item item* Declaration?)*)? }
|
|
|
|
selector {
|
|
UniversalSelector |
|
|
TagSelector { ~item TagName { identifier ~item } } |
|
|
NamespacedTagSelector { ~item (NamespaceName { identifier } | UniversalSelector)? "|" TagName { identifier ~item } } |
|
|
NestingSelector |
|
|
ClassSelector { selector? !attribute "." ClassName { identifier } } |
|
|
PseudoClassSelector {
|
|
selector? !attribute (":" | "::") (
|
|
PseudoClassName { identifier } |
|
|
pseudoClassWithArg ArgList<value+> |
|
|
PseudoClassName { callee } ArgList<selector>)
|
|
} |
|
|
IdSelector { selector? !attribute "#" IdName { identifier } } |
|
|
AttributeSelector {
|
|
selector? !attribute "["
|
|
(AttributeName { identifier } |
|
|
NamespacedAttribute { (NamespaceName { identifier } | UniversalSelector)? "|" AttributeName { identifier } })
|
|
(MatchOp value MatchFlag?)? "]"
|
|
} |
|
|
ChildSelector { selector? !structure ChildOp selector } |
|
|
DescendantSelector { selector !structure descendantOp selector } |
|
|
SiblingSelector { selector? !structure SiblingOp selector }
|
|
}
|
|
|
|
pseudoClassWithArg {
|
|
@specialize[@name=PseudoClassName]<callee, "lang" | "nth-child" | "nth-last-child" | "nth-of-type" | "nth-last-of-type" | "nth-of-type" | "dir" | "host-context">
|
|
}
|
|
|
|
NumberLiteral {
|
|
numberLiteralInner Unit?
|
|
}
|
|
|
|
ArgList<content> { "(" commaSep<content> ")" }
|
|
|
|
Declaration {
|
|
(PropertyName { identifier ~item } | VariableName)
|
|
":" (value (","? value)*)? Important?
|
|
}
|
|
|
|
query {
|
|
KeywordQuery { queryIdentifier } |
|
|
FeatureQuery { "(" FeatureName ":" value+ ")" } |
|
|
BinaryQuery { query !valueOp @specialize[@name=LogicOp]<queryIdentifier, "or" | "and"> query } |
|
|
ComparisonQuery {
|
|
"("
|
|
(queryValue | FeatureName) !valueCompareOp CompareOp (queryValue | FeatureName)
|
|
(!valueCompareOp CompareOp (queryValue | FeatureName))?
|
|
")"
|
|
} |
|
|
UnaryQuery { @specialize[@name=UnaryQueryOp]<queryIdentifier, "not" | "only"> query } |
|
|
ParenthesizedQuery { "(" query ")" } |
|
|
SelectorQuery { queryCalleeKw<"selector"> ParenthesizedSelector } |
|
|
CallQuery { QueryCallee ArgList<FeatureName ":" value+ | query> } |
|
|
PseudoQuery { (":" | "::") queryIdentifier }
|
|
}
|
|
|
|
ParenthesizedSelector { "(" selector ")" }
|
|
|
|
FeatureName { queryIdentifier }
|
|
|
|
value {
|
|
VariableName |
|
|
ValueName { identifier } |
|
|
ParenthesizedValue { "(" token* ")" } |
|
|
BracketedValue { "[" token* "]" } |
|
|
BracedValue { "{" token* "}" } |
|
|
ColorLiteral |
|
|
NumberLiteral |
|
|
StringLiteral |
|
|
BinaryExpression { value !valueOp BinOp value } |
|
|
CallExpression |
|
|
IfExpression |
|
|
CallLiteral
|
|
}
|
|
|
|
token {
|
|
value |
|
|
AtKeyword |
|
|
"#" | ";" | "." | ":"
|
|
}
|
|
|
|
queryValue {
|
|
queryVariableName |
|
|
ColorLiteral |
|
|
NumberLiteral |
|
|
StringLiteral
|
|
}
|
|
|
|
IfExpression {
|
|
@specialize[@name=if]<callee, "if"> ArgList {
|
|
"(" (IfBranch ";")* IfBranch ";"? ")"
|
|
}
|
|
}
|
|
|
|
IfBranch { query ":" value }
|
|
|
|
CallLiteral {
|
|
@specialize[@name=CallTag]<callee, "url" | "url-prefix" | "domain" | "regexp">
|
|
"(" (ParenthesizedContent | StringLiteral)? ")"
|
|
}
|
|
|
|
CallExpression {
|
|
(Callee { callee } | VariableName) !call ArgList<value+>
|
|
}
|
|
|
|
@skip {} {
|
|
Comment[isolate] { "/*" (commentContent | commentLineBreak)* commentEnd }
|
|
}
|
|
|
|
@local tokens {
|
|
commentEnd { "*/" | @eof }
|
|
commentLineBreak { "\n" }
|
|
@else commentContent
|
|
}
|
|
|
|
commaSep<value> { "" | value ("," value?)* }
|
|
|
|
queryKw<name> { @specialize[@name={name}]<queryIdentifier, name> }
|
|
queryCalleeKw<name> { @specialize[@name={name}]<QueryCallee, name> }
|
|
|
|
atKw<name> { @specialize[@name={name}]<AtKeyword, "@" name> }
|
|
|
|
Important { "!" "important" }
|
|
|
|
@external tokens descendant from "./tokens" {
|
|
descendantOp
|
|
}
|
|
|
|
@external tokens unitToken from "./tokens" {
|
|
Unit
|
|
}
|
|
|
|
@external tokens identifiers from "./tokens" {
|
|
identifier,
|
|
callee,
|
|
VariableName
|
|
}
|
|
|
|
@external tokens queryIdentifiers from "./tokens" {
|
|
@conflict { identifier, VariableName, callee }
|
|
queryIdentifier,
|
|
queryVariableName[@name=VariableName],
|
|
QueryCallee
|
|
}
|
|
|
|
@tokens {
|
|
UniversalSelector { "*" }
|
|
|
|
NestingSelector { "&" }
|
|
|
|
AtKeyword { "@" "-"? @asciiLetter (@asciiLetter | @digit | "-")* }
|
|
|
|
MatchOp { $[~^|*$]? "=" }
|
|
|
|
ChildOp { ">" ">"? }
|
|
|
|
CompareOp { $[<>] "="? | "=" }
|
|
|
|
SiblingOp { "~" | "+" }
|
|
|
|
BinOp { $[+\-*/] }
|
|
|
|
MatchFlag { $[SsIi] }
|
|
|
|
whitespace { @whitespace+ }
|
|
|
|
hexDigit { @digit | $[a-fA-F] }
|
|
|
|
ParenthesizedContent { !['")] ![)]+ }
|
|
|
|
@precedence { whitespace, ParenthesizedContent, "/*" }
|
|
|
|
ColorLiteral {
|
|
"#" hexDigit hexDigit hexDigit (hexDigit (hexDigit hexDigit (hexDigit hexDigit)?)?)?
|
|
}
|
|
|
|
numberLiteralInner { ("+" | "-")? (@digit+ ("." @digit*)? | "." @digit+) (("e" | "E") ("+" | "-")? @digit+)? }
|
|
|
|
@precedence { numberLiteralInner, BinOp, SiblingOp }
|
|
|
|
@precedence { numberLiteralInner, "." }
|
|
|
|
StringLiteral[isolate] { "\"" (!["\n\\] | "\\" _)* "\"" | "'" (!['\n\\] | "\\" _)* "'" }
|
|
|
|
"#" "."
|
|
|
|
":" "::" ";" ","
|
|
|
|
"(" ")" "[" "]" "{" "}"
|
|
}
|
|
|
|
@external propSource cssHighlighting from "./highlight"
|
|
|
|
@detectDelim
|