JSFiddle - React, Tailwind, and code Playground

HTML

<script src="http://cloud.github.com/downloads/dmajda/pegjs/peg-0.7.0.js"></script>
<script type="text/html" id="grammar">

start
  = [\n\r]* first:line rest:([\n\r]+ data:line { return data; })* [\n\r]* { rest.unshift(first); return rest; }

line
  = first:field rest:("," text:field { return text; })*
    & { return !!first || rest.length; }
    { rest.unshift(first); return rest; }

field
  = '"' text:char* '"' { return text.join(''); }
  / text:[^\n\r,]* { return text.join(''); }

char
  = '"' '"' { return '"'; }
  / [^"]

</script>

<textarea id="test-csv"></textarea><br>
<button id="parse-button">Parse</button>
<pre id="result"></pre>

CSS

body { padding: 20px; }

textarea {
    width: 600px;
    height: 300px;
}

pre {
    border: 1px solid green;
    padding: 10px;
    margin-top: 20px;
    background-color: #F6F6F6;
}

.error {
    border: 1px solid red;
}

CoffeeScript

csv = """
Year,Make,Model,Description,Price
1997,Ford,E350,"ac, abs, moon",3000.00
1999,Chevy,"Venture ""Extended Edition""\","",4900.00
1999,Chevy,"Venture ""Extended Edition, Very Large""\","",5000.00
1996,Jeep,Grand Cherokee,"MUST SELL!
air, moon roof, loaded",4799.00
"""

$('#test-csv').val csv

grammar = $('#grammar').html()
csvParser = PEG.buildParser(grammar)

$('#parse-button').click ->
    try
        data = csvParser.parse $('#test-csv').val()
        $('#result').removeClass('error').html formatJSON data
    catch error
        $('#result').addClass('error').html formatJSON error





#Utility stuff
RealTypeOf = `function(a){if(typeof a=="object"){if(a===null)return"null";if(a.constructor==(new Array).constructor)return"array";if(a.constructor==(new Date).constructor)return"date";if(a.constructor==(new RegExp).constructor)return"regex";return"object"}return typeof a}`

formatJSON = `function(a,b){if(arguments.length<2){var b=""}var c="    ";var d=RealTypeOf(a);if(d=="array"){if(a.length==0){return"[]"}var e="["}else{var f=0;$.each(a,function(){f++;return});if(f==0){return"{}"}var e="{"}var f=0;$.each(a,function(a,g){if(f>0){e+=","}if(d=="array"){e+="\n"+b+c}else{e+="\n"+b+c+'"'+a+'"'+": "}switch(RealTypeOf(g)){case"array":case"object":e+=formatJSON(g,b+c);break;case"boolean":case"number":e+=g.toString();break;case"null":e+="null";break;case"string":e+='"'+g+'"';break;default:e+="TYPEOF: "+typeof g}f++});if(d=="array"){e+="\n"+b+"]"}else{e+="\n"+b+"}"}return e}`

$('#parse-button').click()