Skip to content

Commit 18c2373

Browse files
author
Joaquin Lorente
committed
Dead-simple grammar that can read natural numbers [funcparserlib]
Funcparserlib is a parser combinator, which means it doesn't use a text-based grammar. Instead, you combine small parsers into larger ones, eventually arriving at a parser that can handle your whole language. The basic unit of funcparserlib is `some`, which takes a function that receives a character and returns a boolean, to determine whether that character is a match. Our `digits` rule is a parser that requires its sub-parser to match one or more times; its sub-parser is a parser that matches if its input is a digit. funcparserlib parsers have an __rshift__ function, which means they can be used with the `>>` operator. However, instead of being a right bit-shift like an int's __rshift__, this function receives a function that takes the output of the parser and returns some munged version of that output. In this case, we're supplying a function that takes the parsed list-of-digit-characters, joins it into a string, and then casts it as an int.
1 parent 0d991d6 commit 18c2373

File tree

3 files changed

+18
-0
lines changed

3 files changed

+18
-0
lines changed

ndn/funcparserlib.py

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from __future__ import absolute_import
2+
3+
import funcparserlib.parser as p
4+
5+
digits = p.oneplus(p.some(lambda char: char.isdigit()))
6+
number = digits >> (lambda ds: int(''.join(ds)))
7+
8+
def calculate(text):
9+
return number.parse(text)

requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ mock==1.0.1
55
rednose==0.4.1
66
ply==3.4
77
parsley==1.2
8+
funcparserlib==0.3.6

test/test_funcparserlib.py

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from unittest import TestCase
2+
from nose.tools import eq_
3+
4+
from ndn.funcparserlib import calculate
5+
6+
class TestParsleyParse(TestCase):
7+
def test_parse_a_single_number(self):
8+
eq_(1, calculate('1'))

0 commit comments

Comments
 (0)