Permalink
Browse files

new simple mode for args

  • Loading branch information...
1 parent 3771fd8 commit a416b8e287153525f258baf17bcda85b1af060f7 @contra contra committed Jun 20, 2012
Showing with 242 additions and 1 deletion.
  1. +3 −1 lib/main.coffee
  2. +141 −0 lib/simple.pegjs
  3. +98 −0 test/simple.coffee
  4. 0 test/{parse.coffee → standard.coffee}
View
@@ -3,6 +3,8 @@
{buildParser} = require 'pegjs'
standard = buildParser String readFileSync join __dirname, 'standard.pegjs'
+simple = buildParser String readFileSync join __dirname, 'simple.pegjs'
module.exports =
- parse: (command) -> standard.parse command
+ parse: (command) -> standard.parse command
+ simple: (command) -> simple.parse command
View
@@ -0,0 +1,141 @@
+start
+ = _ command:command { return command; }
+
+command
+ = head:task tail:(":" _ task)* {
+ var result = {};
+ result[head[0]] = head[1];
+ for (var i = 0; i < tail.length; i++) {
+ result[tail[i][2][0]] = tail[i][2][1];
+ }
+ return result;
+ }
+
+task
+ = name:alphanumeric+ "=" arg:value { return [name.join(""), arg]; }
+ / name:alphanumeric+ "=" chars:alphanumeric+ { return [name.join(""), chars.join("")]; }
+ / name:alphanumeric+ { return [name.join(""), []]; }
+
+alphanumeric
+ = [a-z0-9_]i
+
+/* Everything below is dervived from the PEGJS JSON parser example */
+/*
+ Modifications made:
+ - null actually returns null (kind of a hack around PEG)
+ - undefined added
+*/
+
+object
+ = "{" _ "}" _ { return {}; }
+ / "{" _ members:members "}" _ { return members; }
+
+members
+ = head:pair tail:("," _ pair)* {
+ var result = {};
+ result[head[0]] = (head[1] === "_$null$_" ? null : head[1]);
+ for (var i = 0; i < tail.length; i++) {
+ result[tail[i][2][0]] = (tail[i][2][1] === "_$null$_" ? null : tail[i][2][1]);
+ }
+ return result;
+ }
+
+pair
+ = name:string ":" _ value:value { return [name, value]; }
+
+array
+ = "[" _ "]" _ { return []; }
+ / "[" _ elements:elements "]" _ { return elements; }
+
+elements
+ = head:value tail:("," _ value)* {
+ var result = [head === "_$null$_" ? null : head];
+ for (var i = 0; i < tail.length; i++) {
+ result.push(tail[i][2] === "_$null$_" ? null : tail[i][2]);
+ }
+ return result;
+ }
+
+value
+ = string
+ / number
+ / object
+ / array
+ / "true" _ { return true; }
+ / "false" _ { return false; }
+ / "null" _ { return "_$null$_"; }
+ / "undefined" _ { return undefined; }
+
+/* ===== Lexical Elements ===== */
+
+string "string"
+ = '"' '"' _ { return ""; }
+ / '"' chars:chars '"' _ { return chars; }
+
+chars
+ = chars:char+ { return chars.join(""); }
+
+char
+ // In the original JSON grammar: "any-Unicode-character-except-"-or-\-or-control-character"
+ = [^"\\\0-\x1F\x7f]
+ / '\\"' { return '"'; }
+ / "\\\\" { return "\\"; }
+ / "\\/" { return "/"; }
+ / "\\b" { return "\b"; }
+ / "\\f" { return "\f"; }
+ / "\\n" { return "\n"; }
+ / "\\r" { return "\r"; }
+ / "\\t" { return "\t"; }
+ / "\\u" h1:hexDigit h2:hexDigit h3:hexDigit h4:hexDigit {
+ return String.fromCharCode(parseInt("0x" + h1 + h2 + h3 + h4));
+ }
+
+number "number"
+ = int_:int frac:frac exp:exp _ { return parseFloat(int_ + frac + exp); }
+ / int_:int frac:frac _ { return parseFloat(int_ + frac); }
+ / int_:int exp:exp _ { return parseFloat(int_ + exp); }
+ / int_:int _ { return parseFloat(int_); }
+
+int
+ = digit19:digit19 digits:digits { return digit19 + digits; }
+ / digit:digit
+ / "-" digit19:digit19 digits:digits { return "-" + digit19 + digits; }
+ / "-" digit:digit { return "-" + digit; }
+
+frac
+ = "." digits:digits { return "." + digits; }
+
+exp
+ = e:e digits:digits { return e + digits; }
+
+digits
+ = digits:digit+ { return digits.join(""); }
+
+e
+ = e:[eE] sign:[+-]? { return e + sign; }
+
+/*
+ * The following rules are not present in the original JSON gramar, but they are
+ * assumed to exist implicitly.
+ *
+ * FIXME: Define them according to ECMA-262, 5th ed.
+ */
+
+digit
+ = [0-9]
+
+digit19
+ = [1-9]
+
+hexDigit
+ = [0-9a-fA-F]
+
+/* ===== Whitespace ===== */
+
+_ "whitespace"
+ = whitespace*
+
+// Whitespace is undefined in the original JSON grammar, so I assume a simple
+// conventional definition consistent with ECMA-262, 5th ed.
+whitespace
+ = [ \t\n\r]
View
@@ -0,0 +1,98 @@
+argus = require '../'
+should = require 'should'
+require 'mocha'
+
+testargs = [
+ "string", 'string'
+ true, false
+ 2, -2, 0
+ 2.2, -2.2
+ null,#undefined
+ [{"test":"test"}],["arr1","arr2"]
+ {"test":"~~~test~~"}, {}
+]
+testcli = JSON.stringify testargs
+
+describe 'simple()', ->
+ describe 'standard behaviour', ->
+ it 'task(none)', (done) ->
+ res = argus.simple "task"
+ should.exist res
+ should.exist res.task
+ res.task.should.eql []
+ done()
+ it 'task(all)', (done) ->
+ res = argus.simple "task=#{testcli}"
+ should.exist res
+ should.exist res.task
+ res.task.should.eql testargs
+ done()
+ it 'task(simple)', (done) ->
+ res = argus.simple "task=test"
+ should.exist res
+ should.exist res.task
+ res.task.should.eql "test"
+ done()
+ it 'task(bool)', (done) ->
+ res = argus.simple "task=true"
+ should.exist res
+ should.exist res.task
+ res.task.should.eql true
+ done()
+ it 'task(str)', (done) ->
+ res = argus.simple "task=\"test lol\""
+ should.exist res
+ should.exist res.task
+ res.task.should.eql "test lol"
+ done()
+ it 'task(none):task2(simple)', (done) ->
+ res = argus.simple "task:task2=test"
+ should.exist res
+ should.exist res.task
+ res.task.should.eql []
+ should.exist res.task2
+ res.task2.should.eql "test"
+ done()
+ it 'task(none):task2(all)', (done) ->
+ res = argus.simple "task:task2=#{testcli}"
+ should.exist res
+ should.exist res.task
+ res.task.should.eql []
+ should.exist res.task2
+ res.task2.should.eql testargs
+ done()
+ it 'task(all):task2(none)', (done) ->
+ res = argus.simple "task=#{testcli}:task2"
+ should.exist res
+ should.exist res.task
+ res.task.should.eql testargs
+ should.exist res.task2
+ res.task2.should.eql []
+ done()
+
+ describe 'overloading', ->
+ it 'task(none):task(all)', (done) ->
+ res = argus.simple "task:task=#{testcli}"
+ should.exist res
+ should.exist res.task
+ res.task.should.eql testargs
+ done()
+ it 'task(all):task(none)', (done) ->
+ res = argus.simple "task=#{testcli}:task"
+ should.exist res
+ should.exist res.task
+ res.task.should.eql []
+ done()
+
+ it 'task(none):task(simple)', (done) ->
+ res = argus.simple "task:task=test"
+ should.exist res
+ should.exist res.task
+ res.task.should.eql "test"
+ done()
+ it 'task(all):task(simple)', (done) ->
+ res = argus.simple "task=test:task"
+ should.exist res
+ should.exist res.task
+ res.task.should.eql []
+ done()
File renamed without changes.

0 comments on commit a416b8e

Please sign in to comment.