Backus-Naur Form
Backus-Naur Form (BNF) is not the most concise, nor precise, way of specifying J's syntax. However, some people are familiar with this approach, so it has some educational value.
So, here's a draft presentation of J's syntax in Backus-Naur Form.
Note: this is a first draft, and should be reviewed for potential errors.
Note: This first draft treats "whitespace issues" informally, and only documents J's sentence grammar and does not attempt to document the multi-line grammars used in scripts.
<sentence> ::= <nounclause> | <verbclause> | <adverbphrase> | <conjunctionphrase> | <is> | ( <sentence> )
<nounclause> ::= <noun> | <monad> | <dyad> | <nounphrase>
<verbclause> ::= <verb> | <hook> | <fork> | <verbphrase>
<adverbphrase> ::= <adverb> | <adverbphrase> <adverb> | <adve> | <conje> | <term> <conjunction> | <conjunction> <term>
<conjunctionphrase> ::= <conjunction> | <adve> | <conje>
<is> ::= <lvalue> <assignop> <sentence>
<assignop> ::= =: | =.
<noun> ::= <leftnoun> | <pronoun>
<lvalue> ::= <leftnoun> | <name>
<leftnoun> ::= <numbers> | <literal> | <boxed> | ( <nounclause> )
Note: <noun> and <lvalue> cases are spelled the same way but are treated differently, so are broken out as two distinct cases, to better approximate traditional uses of BNF.
<monad> ::= <verb> <nounphrase>
<dyad> ::= <noun> <verb> <nounphrase>
<verb> ::= <primitiveverb> | <proverb> | ( <verbclause> )
<termphrase> ::= <nounphrase> | <verbphrase>
<fork> ::= <termphrase> <verbphrase> <verbphrase> | <term> <verbphrase> <fork>
<hook> ::= <verbphrase> <verbphrase> | <verbphrase> <fork>
<proverb> ::= <name>
<pronoun> ::= <name>
<proadverb> ::= <name>
<proconjunction> ::= <name>
Note: names are syntactically ambiguous, because their syntactic class depends on their definition.
Note: Undefined names are proverbs.
<nounphrase> ::= <noun> | <adve> | <conje>
<verbphrase> ::= <verb> | <adve> | <conje>
<adverbphrase> ::= <adverb> | <adverbphrase> <adverb> | <adve> | <conje> | <term> <conjunction> | <conjunction> <term>
<conjunctionphrase> ::= <conjunction> | <adve> | <conje>
Note: <adve> and <conje> are syntactically ambigious. Depending on the definition of the adverb or conjunction, they may produce a noun, a verb, an adverb or a conjunction. For example, 0 :'x' is a noun, 1 :'x' is an adverb, 2 :'x' is a conjunction and 4 :'x' is a verb, as is 3 :'x' (but the domain of 3 :'x' is empty).
<adve> ::= <termphrase> <adverb>
<conje> ::= <termphrase> <conjunction> <term>
<term> ::= <noun> | <verb>
<adverb> ::= <primitiveadverb> | <proadverb> | ( <adverbphrase> )
<conjunction> ::= <primitiveconjunction> | <proconjunction> | ( <conjunctionphrase> )
<space> ::= the ascii character with numeric index value 32
<letter> ::= a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
<alphanumeric> ::= letter | alphanumeric letter | alphanumeric numeric
<name> ::= alphanumeric | name . | name :
Note: not all names are valid names. J has special rules about names which end with _ and names which contain two adjacent _ characters. Names which end with . or : are reserved.
<digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | _
<numeric> ::= digit | numeric digit | numeric name
<number> ::= numeric | number . | number . number
<numbers> ::= number | number space numbers
Note: not all numbers are valid numbers. J has special rules about how numbers are translated. For example, 1e5 and 1j5 are valid numbers but 1e and 1j are not valid numbers.
<character> ::= '' | <space> | any printable ascii character except ' | any printable non-ascii unicode character
<characters> ::= <character> | <character> <characters>
<literal> ::= a. | ' characters '
<boxed> ::= a:
<primitiveverb>::= = | < | <. | >: | > | >. | >: | _: | + | +. | +: | * | *. | - | -. | -: | % | %. | %: | ^ | ^. | $ | $. | $: | ~. | ~: | | | |. | |: | , | ,. | ,: | ; | ;: | # | #. | #: | ! | ! | /: | \: | [ | [: | ] | { | {. | {: | {:: | }. | }: | ". | ": | ? | ?. | A. | C. | e. | E. | i. | i: | I. | j. | L. | o. | p. | p.. | p: | q: | r. | s: | u: | x: | _9: | _8: | _7: | _6: | _5: | _4: | _3: | _2: | _1: | 0: | 1: | 2: | 3: | 4: | 5: | 6: | 7: | 8: | 9:
<primitiveadverb> ::= ~ | / | /. | \ | \. | } | b. | f. | M. | t. | t:
<primitiveconjunction> ::= %: | . | .. | .: | : | :. | :: | ;. | !. | !: | " | ` | `: | @ | @. | @: | & | &. | &.: | &: | d. | D. | D: | H. | L: | S: | T.
Note: words which begin with : or with . MUST NOT be preceded by by any character other than space.
Note: adjacent alphanumeric characters will always be a part of the same production.
Note: comments begin with NB. and continue until the end of the line. J ignores everything in comments.