My CSS Grammar

by paulftw

HTML

<script src="http://zaach.github.com/jison/assets/js/jison.js"></script>
<script src="http://zaach.github.com/jison/assets/js/json2.js"></script>
<div id="out"></div>

<textarea id="src" cols="80" rows="7">
    
a, b.x, d#e {
    color: ffc000;
    }
</textarea>

<textarea id="gmr" cols="80" rows="7">
%lex

escape         {unicode}|\\[\x20-\x7E\x80-\xFF]
nonascii       [\200-\377]
nmstart        [a-zA-Z_]|{nonascii}|{escape}

nl             \n|\r\n|\r|\f
wc             [ \t\r\n\f]
w              {wc}*

ident          "-"?{nmstart}{nmchar}*
name           {nmchar}+
unicode        \\[0-9a-fA-F]{1,6}{wc}?
nmchar         [a-zA-Z0-9]|'-'|'_'|{nonascii}|{escape}
num            [0-9]+|[0-9]*"."[0-9]+
stringchar     {urlchar}|\x20|\\{nl}
string         \"({stringchar}|\')*\"|\'({stringchar}|\")*\'
urlchar        [\x9\x21\x23-\x26\x27-\x7E]|{nonascii}|{escape}

%%

{ident}       return 'IDENT'
@{ident}      return 'ATKEYWORD'

#{name}       return 'HASH'
{num}         return 'NUMBER'
{num}%        return 'PERCENTAGE'
{num}{ident}  return 'DIMENSION'

"url("{w}({string}|{urlchar}*){w}")"   return 'URI'
"U+"[0-9A-F?]{1,6}(-[0-9A-F]{1,6})?     return 'UNICODERANGE'

"&lt;!--"     return 'CDO'
"-->"         return 'CDC'
{wc}+         return 'S'

"/*"[^*]*"*"+([^/][^*]*"*"+)*"/"        return 'COMMENT'

{ident}"("    return 'FUNCTION'
"~="          return 'INCLUDES'
"|="          return 'DASHMATCH'
"^="          return 'PREFIXMATCH'
"$="          return 'SUFFIXMATCH'
"*="          return 'SUBSTRINGMATCH'
[^"']         return 'CHAR'


/lex

%start stylesheet

%%

stylesheet_el  : CDO | CDC | S | statement;
stylesheet : 
    /* empty */
    | stylesheet_el stylesheet;
statement   : ruleset | atrule;
atrule     : ATKEYWORD opt_s any* [ block | ';' opt_s ];
block       : '{' opt_s [ any | block | ATKEYWORD opt_s | ';' opt_s ]* '}' opt_s;
ruleset     : selector? '{' opt_s declaration? [ ';' opt_s declaration? ]* '}' opt_s;
selector    : any+;
declaration : property ':' opt_s...

JavaScript

$(function() {

var Jison = require('jison'),
    bnf = require('jison/bnf');

Jison.print = function() {window.console.log(arguments); };
    
$('button').click(function() {
    var grammar = $('#gmr').val();
    var cfg = bnf.parse(grammar);
    
    var parser = new Jison.Generator(cfg, {type: 'lalr'})
        .createParser();    
    var res = parser.parse($('#src').val());
    console.log(res);
    $('#output').html(JSON.stringify(res));
});

$('button').click();
});