Skip to main content

E4X style embedded DSL for Python but without E and X

Project description

P4D is not Python but it is also fun

P4D ( = Python for Data ) is an EasyExtend langlet used to write tree shaped textual data a.k.a XML.

P4D elements are written as statements in a notation being familiar for Python programmers. They closely resemble Python statements. Here is one used to define an element

elm philosophers:
    philosopher:
        name: "Hegel"
        books:
             book( first_edition = 1807):
                title: "Phänomenologie des Geistes"
                language: "german"
    philosopher:
        name: "Leibniz"
        books:
             book( first_edition = 1714):
                title: "Monadologie"
                language: "french"

The elm keyword is new and it is one of the few occasions where P4D breaks actual Python code. However I did not found elm being used in Pythons stdlib so it might break just none.

The subobjects of philosophers can be accessed in E4X style

books = philosophers.philosopher.(name == "Hegel").books
books.book.(@first_edition < 1810).title.text()
# -> "Phänomenologie des Geistes"

P4D can also be used as a template language in the sense that Python expressions can be embedded in P4D elements

L = [1,2,3]
elm A:
    B: &L

elm X:
    & A

The elements of the list object L will be distributed over elements of type B

assert len(A.B) == 3
assert X.A.B[0].text() == '1'

It is easy to convert a P4D element into an XML element using the xmlstr() method. Otherwise one can convert XML to P4D using P4D.from_xml(). This is so easy because internally the same datastructure is used. Building a P4D element and parsing an XML document leads to the same internal representation. This internal representation can be used to store even more distinct objects having quite different properties and are not even textual but binary.

Bytelets

Other than XML and the P4D elements we’ve seen above Bytelets are used to deal with binary data in a flexible manner.

Suppose you want to serialize a string and don’t want to use null-termination. Then you have to send the length of the string together with the string and the type or tag for the receiver to identify the hexcode as a string

elm bl:text:
    Tag: 0x50
    Len: &LEN
    Text: "{obamania}"

This P4D element produces a Bytelet. Bytelets are generally prefixed using the bl namespace prefix. The LEN object is a so called Flow object. It is kind of a dataflow binding. If you bind LEN to a field it computes the sum of the lengths of all values of subsequent fields. If you update the Bytelet the value of the `` Len`` field will be re-computed using LEN.

One can check this out

assert text.Len.hex() == 8

Here 8 is just the length of the text.

new_text = text.clone()
new_text.Text = "{the merkel}"
assert new_text.Len.hex() == 10

One can fully evaluate the text Bytelet

assert text.hex() == 0x50 0x08 0x6F 0x62 0x61 0x6D 0x61 0x6E 0x69 0x61

Notice that writing 0x50 0x08 0x6F ... `` without quotes is valid in P4D and it yields a ``Hex object not a number. So P4D supports enhanced hexadecimal literals which obtain a different semantics than Pythons.

Now we want to turn the Hex object back into a Bytelet for which it has to be parsed. This is done by a Schema

elm bl-schema:TextSchema:
    Tag: 1
    Len: &LEN
    Text: &VAL

parsed = TextSchema.parse(text.hex())
assert parsed.hex()  == text.hex()

A Schema is characterized by the namespace prefix bl-schema. Otherwise it is just another Bytelet with a parse() method. Here the Schema has the exact same structure than the original Bytelet but different field values. The new value VAL is also a dataflow binding. It binds to the Len field. After the value 0x08 is assigned to Len while parsing the VAL binding uses this value to chop of 8 bytes from the input stream and assign it to Text.

More features of Bytelets:

  • Specifications of Bytelets can be refined by setting individual bits and specifying bit array widths.

  • Schemas can be used to parse arbitrary sequences of T(ag)L(ength)V(alue) structures like the one in our example. However the order of the TLVs need not be fixed.

  • Simple arithmetics is defined for Flow objects like LEN and VAL. So we can write Len : &LEN + 1 but also Text: &VAL - VAL["IHL"]*4 where VAL["IHL"] refers not to Len but another field IHL.

For more information look at the P4D documents

http://www.fiber-space.de/EasyExtend/doc/p4d/p4d.html

http://www.fiber-space.de/EasyExtend/doc/p4d/bytelets.html

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

P4D Langlet-1.2.4-py2.5.zip (620.3 kB view details)

Uploaded Source

P4D Langlet-1.2.4-py2.5.tar.gz (482.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

P4D Langlet-1.2.4.win32-py2.5.exe (637.7 kB view details)

Uploaded Source

File details

Details for the file P4D Langlet-1.2.4-py2.5.zip.

File metadata

  • Download URL: P4D Langlet-1.2.4-py2.5.zip
  • Upload date:
  • Size: 620.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for P4D Langlet-1.2.4-py2.5.zip
Algorithm Hash digest
SHA256 4aef6fdd64b0a8269f9d98e27e8cf6cabd57f9aa1565b72c1dd86ace3c4d0d4a
MD5 9d2159177d12c1f4890e70606f99c6c3
BLAKE2b-256 43a58a7237553cd6d8bf03e9a3e653f003a94c13f20ac12030b98ccacc6be94b

See more details on using hashes here.

File details

Details for the file P4D Langlet-1.2.4-py2.5.tar.gz.

File metadata

File hashes

Hashes for P4D Langlet-1.2.4-py2.5.tar.gz
Algorithm Hash digest
SHA256 307d0bdf3fa06bffb04ca86fe51c41e4fb6ef15754312e255ed4c9a682f6fb02
MD5 6440f945e988d151d8e6bae852c40028
BLAKE2b-256 9a92de461679d73caffccf8cf665e869823f6751fde5bcda80771e11db6b985a

See more details on using hashes here.

File details

Details for the file P4D Langlet-1.2.4.win32-py2.5.exe.

File metadata

File hashes

Hashes for P4D Langlet-1.2.4.win32-py2.5.exe
Algorithm Hash digest
SHA256 d4e5d1682906869a28647eeea1279c0d8d5f00e5f880c96f154231c31a01ec50
MD5 3b9db3299eaf31b50187deaae31b9c3b
BLAKE2b-256 2cbbf74af2fe2a7ca01e4f425322c5ceb40e32225ff6451dcef7c1f9b93b399a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page