Skip to content

Formal Syntax Parsing Issues in Lynx CSS Documentation #213

@Dugyu

Description

@Dugyu

Summary

While parsing Formal Syntax strings extracted from Lynx's official CSS property documentation using css-tree's definitionSyntax.parse(), we encountered several failure cases due to either grammar violations or parser limitations (especially when using spec-like notation). This issue documents the exact syntax strings, errors thrown, and their associated propertyName.

Parsing Failures

1. Quantifier on Bracketed Expressions

[<length>]{3}

Property: -x-auto-font-size-preset-sizes

Error:

Unexpected input

Cause: css-tree disallows applying {} quantifiers directly to bracketed expressions.

Fix:

(<length>){3}

2. Quantified Optional Alternatives

true [<length>]{0,3} | false

Property: -x-auto-font-size

Error:

Unexpected input

Fix:

true (<length>){0,3} | false

3. Spec-style where Clauses for Type Definitions

<bg-image> = none | <image> where <image> = <url> | <gradient>

Property: background-image

Error:

Unexpected input

Cause: definitionSyntax.parse() does not support where clauses or inline type aliasing.

Recommendation: Inline type definitions should be separated or pre-registered as custom types.


4. Whitespace Inside Angle-Bracketed Types

<mask-reference >#

Property: mask-image

Error:

Expect `>`

Besides removing the whitespace, we should flatten the nested <image> and <url()> block:

Fix:

mask-image = 
  <mask-reference>#  

<mask-reference> = 
  none       |
  <image>    

<image> = 
  <url()>    |
  <gradient>  

<url()> = 
  url( <string> )

5. Whitespace in Named Type Repetition

<mask-layer >#

Property: mask

Error:

Expect `>`

Fix:

mask = 
  <mask-layer>#  

<mask-layer> = 
  <mask-reference>               ||
  <position> [ / <bg-size> ]?    ||
  <repeat-style>                 ||
  <box>                          ||
  <compositing-operator>         ||
  <masking-mode>                

<mask-reference> = 
  none       |
  <image>    

<image> = 
  <url()>   |
  <gradient>  

<url()> = 
  url( <string> )

<position> = 
  [ left | center | right ] && [ top | center | bottom ]            |
  [ left | center | right | <length-percentage> ] 
    [ top | center | bottom | <length-percentage> ]?                |
  [ [ left | right ] <length-percentage> ] &&
    [ [ top | bottom ] <length-percentage> ]  

<bg-size> = 
  [ <length-percentage> | auto ]{1,2}  |
  cover                                |
  contain                              

<repeat-style> = 
  repeat-x                             |
  repeat-y                             |
  [ repeat | space | round | no-repeat ]{1,2}  

<box> = 
  border-box     |
  padding-box    |
  content-box    

<compositing-operator> = 
  add        |
  subtract   |
  intersect  |
  exclude    

<masking-mode> = 
  alpha         |
  luminance     |
  match-source  

<length-percentage> = 
  <length>      |
  <percentage>  

6. Quantifier on Bracketed Alternates

<bg-size> = [ <length-percentage> | auto ] {1, 2} | cover | contain

Property: background-size

Error:

Unexpected input

Fix:

<bg-size> = (<length-percentage> | auto){1,2} | cover | contain
background-image = <bg-image>#

<bg-image> = none | <image>

<image> = <url()> | <gradient>

<url()> = url(<string>)

<gradient> = <linear-gradient()> | <radial-gradient()>

<linear-gradient()> = 
  linear-gradient( [ <angle> | to <side-or-corner> ]? , <color-stop-list> )

<radial-gradient()> = 
  radial-gradient( [ <ending-shape> || <size> ]? [ at <position> ]? , <color-stop-list> )

<side-or-corner> = 
  [ left | right ] || [ top | bottom ]

<ending-shape> = 
  circle | ellipse

<size> = 
  closest-side       |
  farthest-side      |
  closest-corner     |
  farthest-corner    |
  <length>           |
  <length-percentage>{2}

<position> = 
  [ left | center | right ] || [ top | center | bottom ]                            |
  [ left | center | right | <length-percentage> ] 
    [ top | center | bottom | <length-percentage> ]?                                |
  [ [ left | right ] <length-percentage> ] &&
    [ [ top | bottom ] <length-percentage> ]

<color-stop-list> = <linear-color-stop> ( ',' <linear-color-stop> )*

<linear-color-stop> = <color>

<length-percentage> = <length> | <percentage>

7. Inline Spec Dump (Too Large for One Parse)

<mask-layer> = <mask-reference> || <position> [ / <bg-size> ]? ...

Property: mask

Error:

Expect `>`

Cause: Multiple deeply nested inline type definitions, invalid angle brackets, and unbalanced <...>.

Fix: Split into smaller, composable type definitions or validate manually.


8. Non-standard Formal Syntax Definitions

The following properties either:

  • Are missing ## Formal Syntax sections
  • Contain inline prose with no parseable structure
  • Use semicolon-separated syntax examples (e.g. sample values)
Property Name Problem
clip-path No formal syntax section
css-variable No formal syntax section
order No formal syntax section
position No formal syntax section
relative-center No formal syntax section
relative-id No formal syntax section
row-gap Literal value examples, not grammar

Example for row-gap:

20px; row-gap: 1em; row-gap: 10%; row-gap: calc(10% + 20px)

Error:

Unexpected input

Fix:

row-gap = <length-percentage [0,∞]>

<length-percentage> = <length> | <percentage>

Context

We are building a static extractor that parses Formal Syntax strings from docs/en/api/css/properties/*.mdx, then uses css-tree to validate and eventually convert them into a typed schema to be used in @lynx-js/css-defines.


Suggestions

Would it be feasible to:

  • Improve error reporting for these edge cases?
  • Add support for more spec-style constructs (where, relaxed angle brackets)?
  • Provide a tolerant mode or pre-validator to assist consumers working with documentation-based sources?

We’re happy to contribute fixtures, test cases, or parsing strategies if this is useful.


Metadata

Metadata

Assignees

No one assigned

    Labels

    help wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions