%grammar testml
%version 0.0.1
%include atom
testml-document:
code-section
data-section?
# General Tokens
escape: / [0nt] /
line: / ANY* EOL /
blanks: / BLANK+ /
blank-line: / BLANK* EOL /
comment: / '#' line /
ws: /(: BLANK | EOL | comment )/
# Strings
quoted-string:
| single-quoted-string
| double-quoted-string
single-quoted-string:
/(:
SINGLE
((:
[^ BREAK BACK SINGLE ] |
BACK SINGLE |
BACK BACK
)*?)
SINGLE
)/
double-quoted-string:
/(:
DOUBLE
((:
[^ BREAK BACK DOUBLE] |
BACK DOUBLE |
BACK BACK |
BACK escape
)*?)
DOUBLE
)/
unquoted-string:
/(
[^ BLANKS BREAK HASH]
(:
[^ BREAK HASH]*
[^ BLANKS BREAK HASH]
)?
)/
number: / ( DIGIT+ ) /
# TestML Code Section
code-section: (
| +
| assignment-statement
| code-statement
)*
assignment-statement:
variable-name
/ WS+ '=' WS+ /
code-expression
ending
variable-name: /( ALPHA WORD* )/
code-statement:
code-expression
assertion-call?
ending
ending: /(: ';' | EOL )/ | =ending2
ending2: /- '}'/
code-expression:
code-object
call-call*
call-call:
!assertion-call-test
call-indicator
code-object
code-object:
| function-object
| point-object
| string-object
| number-object
| call-object
function-object:
function-signature?
function-start
( + | assignment-statement | code-statement )*
/- '}'/
function-start: /- ( '{' ) -/
function-signature:
/'(' -/
function-variables?
/- ')'/
function-variables:
function-variable+ % /- ',' -/
function-variable: /( ALPHA WORD* )/
point-object: /( '*' LOWER WORD* )/
string-object: quoted-string
number-object: number
call-object:
call-name
call-argument-list?
call-name: user-call | core-call
user-call: /( LOWER WORD* )/
core-call: /( UPPER WORD* )/
call-indicator: /(: '.' - | - '.' )/
call-argument-list:
/'(' -/
call-argument* % /- ',' -/
/- ')'/
call-argument: code-expression
assertion-call-test: / call-indicator (:EQ|OK|HAS) /
assertion-call:
| +assertion-eq
| +assertion-ok
| +assertion-has
assertion-eq:
| +assertion-operator-eq
| +assertion-function-eq
assertion-operator-eq:
/+ '==' +/
code-expression
assertion-function-eq:
/ call-indicator 'EQ(' /
code-expression
/ ')' /
assertion-ok: assertion-function-ok
assertion-function-ok: / call-indicator ('OK') empty-parens? /
assertion-has: +assertion-operator-has | +assertion-function-has
assertion-operator-has:
/+ '~~' +/
code-expression
assertion-function-has:
/ call-indicator 'HAS(' /
code-expression
/ ')' /
empty-parens: /(: '(' - ')' )/
# TestML Data Section
block-marker: '==='
point-marker: '---'
data-section: data-block*
data-block:
block-header
.( blank-line | comment )*
block-point*
block-header:
block-marker
( blanks block-label )?
blank-line
block-label: unquoted-string
block-point: lines-point | phrase-point
lines-point:
point-marker
blanks
point-name
blank-line
point-lines
point-lines: /(
(:
(!
(: block-marker | point-marker )
SPACE WORD
)
line
)*
)/
phrase-point:
point-marker
blanks
point-name
/ COLON BLANK /
point-phrase
/ EOL /
/(:
comment |
blank-line
)*/
point-name:
/(
user-point-name |
core-point-name
)/
user-point-name: / LOWER WORD* /
core-point-name: / UPPER WORD* /
point-phrase: unquoted-string
# vim: sw=2 lisp: