Skip to content

Commit

Permalink
Fixes #158; Adds Python example
Browse files Browse the repository at this point in the history
Also updates all existing parsers to use an ES6 string literal inside the code so an example can be embedded easily.
  • Loading branch information
Brian Mock committed May 22, 2017
1 parent 8c1d55d commit 8b6767b
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 43 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Parsimmon supports IE7 and newer browsers, along with [Node.js][]. It can be use

## Examples

See the [examples][] directory for annotated examples of parsing JSON, Lisp, and math.
See the [examples][] directory for annotated examples of parsing JSON, Lisp, a Python-ish language, and math.

## Basics

Expand Down
3 changes: 2 additions & 1 deletion examples/.eslintrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"env": {
"node": true
"node": true,
"es6": true
},
"rules": {
"no-console": "off"
Expand Down
37 changes: 22 additions & 15 deletions examples/json.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
var fs = require('fs');
var path = require('path');
var util = require('util');
var P = require('../src/parsimmon');
var P = require('..');

///////////////////////////////////////////////////////////////////////

// Turn escaped characters into real ones (e.g. "\\n" becoems "\n").
// Turn escaped characters into real ones (e.g. "\\n" becomes "\n").
function interpretEscapes(str) {
var escapes = {
b: '\b',
Expand Down Expand Up @@ -96,18 +94,27 @@ var object =

///////////////////////////////////////////////////////////////////////

var source = process.argv[2] || path.resolve(__dirname, '..', 'package.json');
var result = json.parse(fs.readFileSync(source, 'utf-8'));
var text = `\
{
"id": "a thing\\nice\tab",
"another property!"
: "also cool"
, "weird formatting is ok too........😂": 123.45e1,
"": [
true, false, null,
"",
" ",
{},
{"": {}}
]
}
`;

function prettyPrint(x) {
console.log(util.inspect(x, {depth: null, colors: 'auto'}));
var opts = {depth: null, colors: 'auto'};
var s = util.inspect(x, opts);
console.log(s);
}

if (result.status) {
prettyPrint(result.value);
} else {
console.log('Parse failure');
console.log('=============');
console.log();
prettyPrint(result);
}
var ast = json.tryParse(text);
prettyPrint(ast);
22 changes: 9 additions & 13 deletions examples/lisp.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
var fs = require('fs');
var util = require('util');
var P = require('../src/parsimmon');
var P = require('../');

///////////////////////////////////////////////////////////////////////

Expand Down Expand Up @@ -38,18 +37,15 @@ var Lisp = spaced(LExpression);

///////////////////////////////////////////////////////////////////////

var source = process.argv[2];
var result = Lisp.parse(fs.readFileSync(source, 'utf-8'));
var text = `\
(list 1 2 (cons 1 (list)))
`;

function prettyPrint(x) {
console.log(util.inspect(x, {depth: null, colors: 'auto'}));
var opts = {depth: null, colors: 'auto'};
var s = util.inspect(x, opts);
console.log(s);
}

if (result.status) {
prettyPrint(result.value);
} else {
console.log('Parse failure');
console.log('=============');
console.log();
prettyPrint(result);
}
var ast = Lisp.tryParse(text);
prettyPrint(ast);
22 changes: 9 additions & 13 deletions examples/math.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
var fs = require('fs');
var util = require('util');
var P = require('../src/parsimmon');
var P = require('..');

// This parser supports basic math with + - * / ^, unary negation, factorial,
// and parentheses. It does not evaluate the math, just turn it into a series of
Expand Down Expand Up @@ -166,18 +165,15 @@ var MyMath = spaced(tableParser);

///////////////////////////////////////////////////////////////////////

var source = process.argv[2];
var result = MyMath.parse(fs.readFileSync(source, 'utf-8'));
var text = `\
2 + 3 * 4 / 1 - 3 ^ (2!)
`;

function prettyPrint(x) {
console.log(util.inspect(x, {depth: null, colors: 'auto'}));
var opts = {depth: null, colors: 'auto'};
var s = util.inspect(x, opts);
console.log(s);
}

if (result.status) {
prettyPrint(result.value);
} else {
console.log('Parse failure');
console.log('=============');
console.log();
prettyPrint(result);
}
var ast = MyMath.tryParse(text);
prettyPrint(ast);
72 changes: 72 additions & 0 deletions examples/python-ish.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
var util = require('util');
var P = require('..');

///////////////////////////////////////////////////////////////////////

// If this were actually Python, "Block" wouldn't be a statement on its own,
// but rather "If" and "While" would be statements that used "Block" inside.
var Statement =
P.lazy(function() {
return P.alt(ExpressionStatement, Block);
});

// Just a simple `foo()` style function call.
var FunctionCall =
P.regexp(/[a-z]+/).skip(P.string('()'))
.map(function(s) { return ['FunctionCall', s]; })
.desc('a function call');

// To make it a statement we just need a newline afterward.
var ExpressionStatement =
FunctionCall.skip(P.string('\n'));

// The general idea of this is to assume there's "block:" on its own line,
// then we capture the whitespace used to indent the first statement of the
// block, and require that every other statement has the same exact string of
// indentation in front of it.
var Block =
P.seq(
P.string('block:\n'),
P.regexp(/[ ]+/),
Statement
).chain(function(args) {
// `.chain` is called after a parser succeeds. It returns the next parser
// to use for parsing. This allows subsequent parsing to be dependent on
// previous text.
var indent = args[1];
var statement = args[2];
return P.string(indent).then(Statement).many()
.map(function(statements) {
return [statement].concat(statements);
});
})
.map(function(statements) {
return ['Block', statements];
});

///////////////////////////////////////////////////////////////////////

var text = `\
block:
a()
b()
c()
block:
d()
e()
f()
block:
g()
h()
i()
j()
`;

function prettyPrint(x) {
var opts = {depth: null, colors: 'auto'};
var s = util.inspect(x, opts);
console.log(s);
}

var ast = Block.tryParse(text);
prettyPrint(ast);

0 comments on commit 8b6767b

Please sign in to comment.