Skip to content

Commit

Permalink
Merge pull request #159 from /issues/158
Browse files Browse the repository at this point in the history
Fixes #158; Adds Python example
  • Loading branch information
Brian Mock committed May 22, 2017
2 parents 8c1d55d + 8b6767b commit ccf3f64
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 ccf3f64

Please sign in to comment.