Description#
Implement a CSS parser in the css crate that consumes tokens from the CSS tokenizer and produces a structured stylesheet (CSSOM). Follow CSS Syntax Module Level 3 (§5 Parsing).
Acceptance Criteria#
- Parse stylesheet into a list of rules, where each rule has:
- A selector list (comma-separated selectors)
- A declaration block (property-value pairs)
- Selector parsing — support these selector types:
- Type selectors:
div,p,h1 - Universal selector:
* - Class selectors:
.classname - ID selectors:
#idname - Attribute selectors:
[attr],[attr=value],[attr~=value],[attr|=value],[attr^=value],[attr$=value],[attr*=value] - Combinators: descendant (space), child (
>), adjacent sibling (+), general sibling (~) - Compound selectors:
div.class#id - Selector lists:
h1, h2, h3 - Pseudo-classes (store as name, matching is in style crate):
:hover,:first-child,:last-child, etc.
- Type selectors:
- Declaration parsing:
- Property name and value pairs separated by
: - Values as a list of component values (tokens)
!importantflag- Graceful error recovery: skip invalid declarations, don't abort the rule
- Property name and value pairs separated by
- @-rules (basic):
@media(parse the prelude; nested rules)@import(parse URL string)
- Represent the parsed stylesheet as a Rust data structure (Vec of rules)
- Write tests for selector parsing, declaration parsing, error recovery, @-rules
Dependencies#
- CSS tokenizer (previous issue)
Implementation Notes#
- No external dependencies
- Parse
<style>element content and inlinestyle=""attribute values - Error recovery is important: real-world CSS has errors, parser must not panic