Skip to content

Instantly share code, notes, and snippets.

@itsbth
Created January 6, 2012 19:10
Show Gist options
  • Select an option

  • Save itsbth/1571956 to your computer and use it in GitHub Desktop.

Select an option

Save itsbth/1571956 to your computer and use it in GitHub Desktop.
Uploaded by UploadToGist for Sublime Text 2
{Parser} = require 'jison'
# Stolen from coffee-script
# Since we're going to be wrapped in a function by Jison in any case, if our
# action immediately returns a value, we can optimize by removing the function
# wrapper and just returning the value directly.
unwrap = /^function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/
# Our handy DSL for Jison grammar generation, thanks to
# [Tim Caswell](http://github.com/creationix). For every rule in the grammar,
# we pass the pattern-defining string, the action to run, and extra options,
# optionally. If no action is specified, we simply pass the value of the
# previous nonterminal.
o = (patternString, action, options) ->
patternString = patternString.replace /\s{2,}/g, ' '
return [patternString, '$$ = $1;', options] unless action
action = if match = unwrap.exec action then match[1] else "(#{action}())"
action = action.replace /\bnew /g, '$&yy.'
action = action.replace /\b(?:Block\.wrap|extend)\b/g, 'yy.$&'
[patternString, "$$ = #{action};", options]
# End coffee-script loot
t = (regex, name) ->
[regex.toString().slice(1, -1), if name then "return #{JSON.stringify(name)};" else "/* om nom nom */"]
grammar = lex: {}
grammar.lex.rules = [
t /@.+\n/, 'DIRECTIVE'
t /\s+/
t /[0-9]+(?:\.[0-9]+)?\b/, 'NUMBER'
t /(["'])(?:\\?.)*?\1/, 'STRING'
t /\*/, '*'
t /\//, '/'
t /\+/, '+'
t /\-/, '-'
t /\=/, '='
t /\(/, '('
t /\)/, ')'
t /\?/, '?'
t /:/, ':'
t /\{/, '{'
t /\}/, '}'
t /\[/, '['
t /\]/, ']'
t /if/, 'IF'
t /else/, 'ELSE'
t /elseif/, 'ELSEIF'
t /while/, 'WHILE'
t /[a-z][A-Za-z0-9_]+/, 'FUNC'
t /[A-Z][A-Za-z0-9_]+/, 'VAR'
t /@/, '@'
t /$/, 'EOF'
]
for assoc in ['left', 'right', 'nonassoc']
o[assoc] = (args...) -> [assoc, args...]
grammar.operators = [
o.left ':'
].reverse()
grammar.bnf =
Root: [
o 'DirectiveList StatementList EOF', -> new Root $1, $2
o 'StatementList EOF', -> new Root [], $1
]
DirectiveList: [
o 'DirectiveList DIRECTIVE', -> $1.push $2; $1
o 'DIRECTIVE', -> [$1]
]
StatementList: [
o 'StatementList Statement', -> $1.push $2; $1
o 'Statement', -> [$1]
]
Statement: [
o 'Assignable = Expression', -> new Assignment $1, $3
#o 'Expression'
]
Expression: [
o 'Literal', -> new Literal $1
o 'VAR', -> new Var $1
o '( Expression )', -> $2
]
Literal: [
o 'NUMBER', -> parseFloat($1)
o 'STRING', -> $1.slice 1, -1
]
Assignable: [
o 'Assignable [ Expression ]', -> new Access $1, $3
o 'VAR', -> new Var $1
]
# Return from the root node
for pattern in grammar.bnf.Root
pattern[1] = "return #{pattern[1]}"
exports.parser = new Parser(grammar)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment