普遍版的 CSS 2.1 錯誤修復語法(所謂核心語法)

CSS 2.1 在解析的錯誤處理方面,有一個乍看之有點道理的所謂的核心語法[1]:

  # 使用者代理會根據解析錯誤的處理規則,忽略樣式表中可以用下面文法但是不
  # 能用附錄 G 的文法解析的部份。

  # CSS 與未來的所有擴展不使用 "unused" 產生式,它的作用僅是幫助錯誤處
  # 理。(參見 4.2 解析錯誤的處理規則。)

  # 在有些情形中,使用者代理必須忽略不合法樣式表的一部分。本規範定義忽略
  # 的意義如下:使用者代理解析不合法的部份(為了找到不合法部份的起點和終
  # 點),但是當作這部份不存在來處理。

這些話可以用來解釋規範裡某些比較難懂的例子,例如:

  # 以下全部相等:
  #   p { color:green }
  #   ...
  #   p { color:green; color{;color:maroon} }

因為按照

  # block      : '{' S* [ any | block | ATKEYWORD S* | ';' S* ]* '}' S*;
  # ...
  # declaration: property S* ':' S* value;
  # ...
  # value      : [ any | block | ATKEYWORD S* ]+;

 "{;color:maroon}" 可以被 tokenize 成 '{' ';' IDENT ':' IDENT '}',解析
成 '{' ';' any any any '}' → block → value,所以會被一起丟掉。

但是這個核心語法其實對規範*自己*的某些例子就不適用了,例如:

  p @here {color: red}

因為 ATKEYWORD(@here)不能解析 any,所以 "p @here" 也不能解析成一個
selector。也就是,這個核心語法不能解釋這個例子,事實上,這個核心語法不能
解釋「敘述格式異常」裡的所有例子。


這個乍看有用其實不完全的核心語法一直受到批評,在 www-style 可以看到從
2009 直到 2011 年 CSS 2.1 變成 REC 都有看到對這個地方不滿的回饋。

我最近發現這個核心語法其實可以擴展成一個普遍文法[2],所謂的普遍語法(我
也沒修過編譯器的課),是指任何輸入都可以解析的語法。我把這個文法寫到 CSS
2.1 翻譯的討論頁面[3]了,也留了一些說明和其他參考資料。


附上實作這個語法的 bison+flex 檔案。在 Mac OS X 上用

  flex scan3.l
  bison -v -d css.y
  clang css.tab.c lex.yy.c
  cat EXAMPLE.css | ./a.out

就可以跑了。舉個例子,上面的例子,用這個解析器就會給出:

[[
declaration:
color : green

declaration:
color {
 ; color : maroon}


ruleset:
p  {
  color : green;
  color {
 ; color : maroon}
}
]]

也就是 "color: maroon" 不是一個 declaration。其他例子 CSS 2.1 的測試資料
[4]裡還有很多奇奇怪怪的,對這方面想多了解的可以找來玩。

(我用來搞定 bison 花的時間比寫下這個文法還來的長,所以假如執行這個有問
題的歡迎私信問我。)


我在討論頁留了一些還沒有做得事的列表:

* 完整測試這個語法的瀏覽器兼容狀況(特別是 BAD_URI、CDO、CDC 的部份)
* 寫出 @media 的 block 內容語法(其實就是 at-rule、ruleset 前面都不能有
'}' 的 stylesheet。)也要測試一下有沒有在這個地方不省略 CDO、CDC 的瀏覽器。
* 用 EBNF 的 '-' 號讓這個文法更好讀。
* 了解這是 L-?
* 了解各 CSS 解析引擎用(例如:SASS)的合不合這個文法,還是拋錯。

有興趣的可以試試看再來討論。

[1] http://www.w3.org/html/ig/zh/wiki/CSS2#core-grammar
[2] http://en.wikipedia.org/wiki/Context-free_grammar#Universality
[3] http://www.w3.org/html/ig/zh/wiki/Talk:CSS2#core-grammar
[4]
http://test.csswg.org/suites/css2.1/nightly-unstable/xhtml1/chapter-4.xht#s4.1.6

Received on Tuesday, 5 June 2012 11:29:20 UTC