This is the complete Extended Backus Normal Form (eBNF) grammar definition for Tortuga.

Syntax Grammar

The syntactic grammar of Tortuga is used to parse a linear sequence of tokens into a nested syntax tree structure. The root of the grammar matches an entire Tortuga program (or a sequence of comparisons to make the interpreter more useful).

program     = expressions | comparisons EOF ;
expressions = expression+ ;
comparisons = expression comparison+ ;
comparison  = comparator expression ;

Expression

A program is a series of expressions. Expressions produce values. Tortuga has a number of binary operators with different levels of precedence. Some grammars for languages do not directly encode the precedence relationships and specify that elsewhere. Here, we use a separate rule for each precedence level to make it explicit.

expression = assignment | arithmetic ;
assignment = function "=" block ;
block      = "[" expression expression+ "]" | expression ;

arithmetic = epsilon ;
epsilon    = modulo ( "~" modulo )? ;
modulo     = sum ( "%" sum )* ;
sum        = product ( ( "+" | "-") product )* ;
product    = power ( ( "*" | "/" ) power )* ;
power      = primary ( "^" primary )* ;

call       = primary arguments* ;
primary    = number | IDENTIFIER | grouping ;
number     = "-"? NUMBER ;
grouping   = "(" expression ")" ;

Pattern Rules

The grammar allows pattern-matching in function definitions instead of having built-in control flow. These rules define the allowed patterns.

pattern    = function | refinement | bounds ;
function   = name parameters? ;
refinement = name comparator arithmetic ;
bounds     = arithmetic inequality name inequality arithmetic ;

Utility Rules

To keep the above rules a little cleaner, some grammar is split out into a few reused helper rules.

arguments  = "(" expression ( "," expression )* ")" ;
parameters = "(" pattern ( "," pattern )* ")" ;

name       = "_" | "@" IDENTIFIER ;
inequality = "<" | "<=" | ">" | ">=" ;
equality   = "=" | "<>" ;
comparator = equality | inequality ;

Lexical Grammar

The lexical grammar is used during lexical analysis to group characters into tokens. Where the syntax is context free, the lexical grammar is regular – note that there are no recursive rules.

IDENTIFIER  = XID_START XID_CONTINUE* ;
NUMBER      = NONZERO DIGIT? "#" ( "0" | NATURAL | REAL | FRACTION) ;
NATURAL     = NZ_ALPHANUM ALPHANUM* ( "." "0"? )? ;
REAL        = NZ_ALPHANUM ALPHANUM* "." ALPHANUM*? NZ_ALPHANUM ;
FRACTION    = "0"? "." ALPHANUM*? NZ_ALPHANUM ;

NZ_ALPHANUM = NZ_DIGIT | ALPHA ;                
ALPHANUM    = DIGIT | ALPHA ;
ALPHA       = "a" ... "z" | "A" ... "Z" ;
NZ_DIGIT    = "1" ... "9" ;
DIGIT       = "0" ... "9" ;

Operators

The associativity and precedence of the various operators in Tortuga are defined below.

PrecedenceOperationSymbolLeft AssociativeRight AssociativeNon-Associative
1Epsilon~X
2Modulo%XX
3Add+XX
3Subtract-X
4Multiply*XX
4Divide/X
5Exponent^X
6Pattern Match=X
7Inequality<>XX
7Less Than<XX
7Less Than or Equal To<=XX
7Greater Than>XX
7Greater Than or Equal To>=XX