-
Notifications
You must be signed in to change notification settings - Fork 42
Home
knipknap edited this page Sep 13, 2010
·
17 revisions
Gelatin is a combined lexer, parser, and output generator. It is a simple language for converting text into a structured formats.
Suppose you want to convert the following text file to XML:
User ---- Name: John, Lastname: Doe Office: 1st Ave Birth date: 1978-01-01
User ---- Name: Jane, Lastname: Foo Office: 2nd Ave Birth date: 1970-01-01
The following Gelatin syntax does the job:
# Define commonly used data types. This is optional, but # makes your life a litte easier by allowing to reuse regular # expressions in the grammar. define nl /[\r\n]/ define ws /\s+/ define fieldname /\w+/ define value /[^\r\n,]/ define field_end /[\r\n,]/
grammar user: match nl: do.return() match ws: do.next() match fieldname ':' ws value field_end: out.add('$0', '$3')
# The grammar named "input" is the entry point for the converter. grammar input: match 'User' nl '----': out.enter('user') user()
Explanation:
- “grammar input:” is the entry point for the converter.
- The match statements in each grammar are executed sequentially. If a match is found, the statements under the match are executed, and the grammar is re-executed sequentially.
- If the end of a grammar is reached before the end of the input document was reached, an error is raised.
- out.add(‘$0’, ‘$3’) creates a node in the XML (or JSON, or YAML). The name of the node is the value of the first matched field (the fieldname, in this case). The data of the node is the value of the fourth matched field.
- out.enter(‘user’) creates a “user” node in the output and selects it such that all following “add” statements generate output relative to the “user” node. Gelatin automatically leaves the user node upon leaving the match statement.
- user() calls the grammar named “user”.
The following command converts the input to XML:
./gel -s mysyntax.gel input.txt
The some for JSON or YAML:
./gel -s mysyntax.gel -f json input.txt
./gel -s mysyntax.gel -f yaml input.txt
grammar input:
match 'User' nl '----' nl 'Name:' ws value field_end:
out.enter('user?name="$6"')
user()
match /# .*[\r\n]/:
do.skip()
match /# .*[\r\n]/
| '/*' /[^\r\n]/ '*/' nl:
do.skip()