W3CºÎ·Ï D. CSS2ÀÇ ¹®¹ýTrio ȨÆäÀÌÁö 

¸ñÂ÷

ÀÌ ºÎ·ÏÀº Áö¸íÀûÀÌ´Ù.

¾Æ·¡ ¹®¹ýÀº CSS2ÀÇ ¹®¹ýÀ» Á¤ÀÇÇÑ´Ù. ±×·¯³ª, ¾î¶² Àǹ̿¡¼­´Â ÀÌ´Â ÀÌ ±Ô°ÝÀÇ Ãß°¡ÀûÀÎ ¹®¸ÆÀûÀÎ Á¦ÇÑÀÌ ÀÌ ¹®¹ý¿¡´Â Ç¥½ÃµÇÁö ¾ÊÀº CSS2ÀÇ »óÀ§ ¼¼Æ®(superset)ÀÌ´Ù. ±Ô°Ý¿¡ ºÎÇÕÇÏ´Â »ç¿ëµµ±¸´Â ÇâÈÄ ¹öÀü¿¡ ºÎÇÕÇÑ ¸í·É Çؼ®(parsing), ¼Ó¼º°ú °ª Ç¥±â¿Í ´ÜÀ§(unit) Ç¥±â(notation)µµ ÁؼöÇÏ¿©¾ß ÇÑ´Ù. ¿¹¸¦ µé¾î "class" ¾ÖÆ®¸®ºäÆ®(attribute)ÀÇ °¡´ÉÇÑ °ªµé¿¡ ´ëÇÑ Á¦ÇÑ°ú °°Àº, Ãß°¡ÀûÀ¸·Î ¹®¼­¾ð¾îÀÇ Á¦ÇÑÀÌ °¡ÇØ Áú ¼ö ÀÖ´Ù

D.1 ¹®¹ý

¾Æ·¡ ¹®¹ýÀº LL(1)ÀÌ´Ù. ±×·¯³ª, ÀÌ´Â CSS2 ¹®¹ý ÀÏ »ÓÀ̸ç, Çؼ®(parsing) ¸ñÀûÀ¸·Î Ç¥ÇöµÈ °ÍÀÌ ¾Æ´Ï¹Ç·Î, ´ëºÎºÐ »ç¿ëµµ±¸µéÀº Á÷Á¢ÀûÀ¸·Î »ç¿ëÇÏÁö ¸»¾Æ¾ß ÇÑ´Ù´Â Á¡¿¡ À¯ÀÇÇ϶ó. ÀÌ ¾ç½ÄÀº Àΰ£ÀÇ »ç¿ë¿¡ ÀûÇÕÇÏ°Ô ¸¸µé¾î Á³À¸¸ç, ÀϺΠ¾à½Ä ¸í·É Ç¥±â´Â Yacc([YACC] ÂüÁ¶) ¹üÀ§ ¹ÛÀÌ´Ù:

°á°ú¹°µéÀº:

stylesheet
  : [ CHARSET_SYM S* STRING S* ';' ]?
    [S|CDO|CDC]* [ import [S|CDO|CDC]* ]*
    [ [ ruleset | media | page | font_face ] [S|CDO|CDC]* ]*
  ;
import
  : IMPORT_SYM S*
    [STRING|URI] S* [ medium [ ',' S* medium]* ]? ';' S*
  ;
media
  : MEDIA_SYM S* medium [ ',' S* medium ]* '{' S* ruleset* '}' S*
  ;
medium
  : IDENT S*
  ;
page
  : PAGE_SYM S* IDENT? pseudo_page? S*
    '{' S* declaration [ ';' S* declaration ]* '}' S*
  ;
pseudo_page
  : ':' IDENT
  ;
font_face
  : FONT_FACE_SYM S*
    '{' S* declaration [ ';' S* declaration ]* '}' S*
  ;
operator
  : '/' S* | ',' S* | /* empty */
  ;
combinator
  : '+' S* | '>' S* | /* empty */
  ;
unary_operator
  : '-' | '+'
  ;
property
  : IDENT S*
  ;
ruleset
  : selector [ ',' S* selector ]*
    '{' S* declaration [ ';' S* declaration ]* '}' S*
  ;
selector
  : simple_selector [ combinator simple_selector ]*
  ;
simple_selector
  : element_name? [ HASH | class | attrib | pseudo ]* S*
  ;
class
  : '.' IDENT
  ;
element_name
  : IDENT | '*'
  ;
attrib
  : '[' S* IDENT S* [ [ '=' | INCLUDES | DASHMATCH ] S*
    [ IDENT | STRING ] S* ]? ']'
  ;
pseudo
  : ':' [ IDENT | FUNCTION S* IDENT S* ')' ]
  ;
declaration
  : property ':' S* expr prio?
    | /* empty */
  ;
prio
  : IMPORTANT_SYM S*
  ;
expr
  : term [ operator term ]*
  ;
term
  : unary_operator?
    [ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* | ANGLE S* |
    TIME S* | FREQ S* | function ]
    | STRING S* | IDENT S* | URI S* | RGB S* | UNICODERANGE S* | hexcolor
  ;
function
  : FUNCTION S* expr ')' S*
  ;
/* color´Â ´ÙÀ½ Á¦ÇÑÀ» °®´Â´Ù.
  * 3 °³ ¶Ç´Â 6 °³ÀÇ 16Áø¼ö(0-9a-fA-F)¸¦ °¡Áü.

 "#" ´ÙÀ½¿¡; ¿¹ "#000"´Â µÇ³ª "#abcd"´Â ¾ÈµÊ. */
hexcolor
  : HASH S*
  ;

D.2 Lexical scanner

´ÙÀ½Àº ÈÇ·º½º(Flex) Ç¥±â([FLEX] ÂüÁ¶)·Î ¾²¿©Áø ÅäÅ«È­(tokenizer)ÀÌ´Ù. ÀÌ ÅäÅ«È­´Â ´ë¼Ò¹®ÀÚ¸¦ ±¸º°ÇÑ´Ù.

µÎ ¹øÀÇ "\377"´Â ÇöÀç Flex ¹öÀüÀÇ Ãë±ÞÇÒ ¼ö ÀÖ´Â °¡Àå ³ôÀº ±ÛÀÚ ¹øÈ£¸¦ ³ªÅ¸³½´Ù(½ÊÁø¼ö 255). ÀÌ´Â À¯´ÏÄÚµå(Unicode: /ISO-10646)¿¡¼­ °¡´ÉÇÑ °¡Àå ³ôÀº ÄÚµå Æ÷ÀÎÆ®ÀÎ "\4177777"(½ÊÁø¼ö 1114111)·Î ÀÐÇôÁ®¾ß ÇÑ´Ù.

%option case-insensitive

h  [0-9a-f]
nonascii  [\200-\377]
unicode  \\{h}{1,6}[ \t\r\n\f]?
escape {unicode}|\\[ -~\200-\377]
nmstart  [a-z]|{nonascii}|{escape}
nmchar  [a-z0-9-]|{nonascii}|{escape}
string1  \"([\t !#$%&(-~]|\\{nl}|\'|{nonascii}|{escape})*\"
string2  \'([\t !#$%&(-~]|\\{nl}|\"|{nonascii}|{escape})*\'

ident {nmstart}{nmchar}*
name {nmchar}+
num  [0-9]+|[0-9]*"."[0-9]+
string {string1}|{string2}
url  ([!#$%&*-~]|{nonascii}|{escape})*
w  [ \t\r\n\f]*
nl  \n|\r\n|\r|\f
range  \?{1,6}|{h}(\?{0,5}|{h}(\?{0,4}|{h}(\?{0,3}|{h}(\?{0,2}|{h}(\??|{h})))))

%%

[ \t\r\n\f]+ {return S;}

\/\*[^*]*\*+([^/][^*]*\*+)*\/ /* ÁÖ¼® ¹«½Ã ignore comments */

"<!--" {return CDO;}
"-->" {return CDC;}
"~=" {return INCLUDES;}
"|=" {return DASHMATCH;}

{string} {return STRING;}

{ident} {return IDENT;}

"#"{name} {return HASH;}

"@import" {return IMPORT_SYM;}
"@page" {return PAGE_SYM;}
"@media" {return MEDIA_SYM;}
"@font-face" {return FONT_FACE_SYM;}
"@charset" {return CHARSET_SYM;}
"@"{ident} {return ATKEYWORD;}

"!{w}important" {return IMPORTANT_SYM;}

{num}em {return EMS;}
{num}ex {return EXS;}
{num}px {return LENGTH;}
{num}cm {return LENGTH;}
{num}mm {return LENGTH;}
{num}in {return LENGTH;}
{num}pt {return LENGTH;}
{num}pc {return LENGTH;}
{num}deg {return ANGLE;}
{num}rad {return ANGLE;}
{num}grad {return ANGLE;}
{num}ms {return TIME;}
{num}s {return TIME;}
{num}Hz {return FREQ;}
{num}kHz {return FREQ;}
{num}{ident} {return DIMEN;}
{num}% {return PERCENTAGE;}
{num} {return NUMBER;}

"url("{w}{string}{w}")" {return URI;}
"url("{w}{url}{w}")" {return URI;}
{ident}"(" {return FUNCTION;}

U\+{range} {return UNICODERANGE;}
U\+{h}{1,6}-{h}{1,6} {return UNICODERANGE;}

. {return *yytext;}

D.3 CSS2¿Í CSS1¿¡¼­ ÅäÅ«È­ ºñ±³

¹ø¿ª¹® CSS1 Ãßõ¾È°ú À§¿¡ Á¦½ÃµÈ ¹®¹ý¿¡´Â ÀϺΠÂ÷À̵éÀÌ ÀÖ´Ù. ÀÌµé ´ëºÎºÐÀº CSS1¿¡´Â ¾ø¾ú´ø CSS2ÀÇ »õ·Î¿î ÅäÅ«(token)µé¿¡ ±âÀÎÇÑ °ÍÀÌ´Ù. ´Ù¸¥ °ÍµéÀº ¹®¹ýÀÌ ´õ Àб⠽±°Ô ´Ù½Ã ¾²¿©Á³±â ¶§¹®ÀÌ´Ù. ±×·¯³ª, ÀϺΠ¼­·Î ÅëÇÏÁö ¾Ê´Â(incompatible) º¯°æµéÀÌ Àִµ¥, À̵éÀº CSS1 ¹®¹ý¿¡¼­ ¿À·ù·Î ´À²¸Á³¾ú´Ù. À̵éÀ» ¾Æ·¡¿¡ ¼³¸íÇÑ´Ù.


ÆäÀÌÁö ¸ÇÀ§·Î¸ÇÀ§ÀÌ Trio ȨÆäÀÌÁö ¹®¼­()´Â ÀÚÀ¯·ÎÀÌ ¿¬°á »ç¿ëÀÌ °¡´ÉÇÔ.
(¼öÁ¤ÀÏ )