This page has been written by Hubert Tonneau, then enhanced by William Merriam.

The Pliant parser is original in that it doesn't rely on an automaton derived from a grammar. It is simpler, but more customizable and therefore much more powerful.

The syntax introduced below should not be seen as imposed by Pliant; it is simply the default. It has been designed to be the cleanest ever built (needing the smallest number of non-significant symbols). However, keep in mind that if you don't like it, it is possible to write a module that extends it, or even changes it.

In C, a function call with two arguments is written


whereas in Pliant it is written

(foo 3 5)

The '#' symbol introduces a comment which will end at the end of the line

console "Hello world" eol # This is my first program.

5  -12  2Ch  0B74Eh  10010010b

Numbers written in hexadecimal must start with a decimal digit (zero if the first significant digit is a letter) and end with a lower-case 'h'. The digits from 'A' to 'F' must be upper case. Similarly, numbers written in binary notation must end in a lower-case 'b'.

10.3  -1.27e-3

"abc"  "abc def["]ghi"

The second string is parsed as

abc def"ghi

Here is the list of all valid character sequences for encoding special characters:
[lb] [ left bracket
[rb] ] right bracket
[dq] " double quote
[cr] carriage return
[lf] line feed
[tab] tabulation
[0] character number 0

abc  abc_def32 'abc' 'abc def'

An identifier may be quoted. It must be quoted if it contains a character which is not a non-accented letter, a numerical digit or an underscore, or if it starts with a numerical digit.

The link operator is ':'. As an example:


is parsed as

(((abc def) ghi) jkl)

The separation operation is ';' . As an example:

abc def ; ghi jkl mno ; pqr stu

is parsed as

{ (abc def) (ghi jkl mno) (pqr stu) }

abc def := ghi jkl mno

is parsed as

( ':=' (abc def) (ghi jkl mno) )

The ':>' operator has exactly the same syntax as ':=' but has a different meaning.

not condition
condition1 and condition2
condition1 or condition2

'not' is wrapped before 'and', which is wrapped before 'or'. As an example:

c1 or not c2 and c3

is equivalent to

c1 or ((not c2) and c3)

and and or are shortcut evaluated.
a+b addition
-a negation (unary minus)
a-b subtraction
a*b multiplication
a\b integer division
a/b floating point division
a%b modulus (remainder)
a^b exponentiation (raising to a power)

The behavior of '-' operator is a bit more complex:
expression parsed as
a - b ('-' a b)
a -b (a ('-' b))
a-b ('-' a b)
That is, '-' is a binary operator unless it follows a space and is not followed by a space.

.not. .or. .and. .xor. operators are bitwise operators equivalent to the ~ | & ^ operators of C.

.+. .-. .*. .^. operators are the same as + - * ^ but do not generate an error on overflow.
As an example, in a 32-bit environment,


will generate an overflow error, while


will not.

Please note that there are no bit-shift operators (equivalent to << and >> in C) in Pliant since the ^ operator, which does not exist in C, can replace them.


This is used to introduce a function's result. See the 'factorial' function below for an example.
Here is the list of all predefined operators sorted by decreasing precedence. All operators on the same line have the same precedence and are therefore evaluated from left to right.
operators priority
; 520h
:=  :> 510h
unary - 490h changed around R23
: 410h
^ .^. 330h
* / \ % .*. 320h
+ - .+. .-. 310h
.not. 2A0h changed around R23
.and. .or. .xor. 290h changed around R23
< > <= >= = <> 210h
not 130h
and 120h
or 110h

The following program:

abc def gh
  ijk lm
    nop qr st

Produces the same parsed tree as the following line:

(abc def gh { (ijk lm) (nop qr st) } )

The rules are very simple to deduce:

These rules are very simple and efficient, and avoid most ( ) and { }
As an example, here is the definition of the 'factorial' function:

function factorial x -> f
  arg Int x f
  if x=0
    f := 1
    f := x * (factorial x-1)

Tabs are not allowed in the source code: you have to use spaces instead. The main reason for not allowing them is that not everybody agrees on the number of spaces each tab stands for, so when a program contains several modules provided by different people, the number could be different in various modules. Tabs could be allowed if the number of spaces they stood for were declared at the beginning of the module, but then the various editors would have to be aware of that ... so it is simpler to use only spaces. Furthermore, most editors provide a 'translate tabs to spaces' function.

Pliant's default syntax is lighter than others because: