JXN Syntax Definition (in a modified EBNF)
If you are not familiar with BNF or EBNF you may skip the following detailed description of the JXN grammar.
EBNF Operators and Symbols ( → Wikipedia: de | en )
EBNF-Operators: non_terminal = definition , ? informal description ? , /* comment */ , // comment
alternative1 | alternative2 , [ option 0,1 ] , { optional repetition 0,* } , ( grouping )
EBNF-Terminal-Symbols (JXN operators): special character in quotes e.g. "=", "+", "@"
EBNF-Non-Terminal-Symbols (abstract terms of JXN): word without blanks e.g. expression, special_command
Keywords (-> JXN special_commands): # followed by underlined word e.g. #import
If not stated differently arbitrary blanks are allowed before and between terminal symbols and non-terminal symbols
JXN Syntax
command = [ special_command | statement_sequence ] [ jxn_comment ]
special_command = #filespec | #import | #remove | #edit | #reinit | #exit
| #function | #if | #ifdef | #ifndef | #else if | #else | #endif | #while | #break | #continue | #endwhile | #return | #endfunction
statement_sequence = statement { ";" statement } [ ";" ] // trailing ";" supresses result output
jxn_comment = "!" ? random text ?
statement = [ variable_name "=" ] expression | variable_name "=" // "name=" repeats the most recent assignment statement to variable name
// L-values not (yet) implemented:
| symbolic_factor_extended "[" expression "]" "=" expression // workaround: set( symbolic_factor_extended, index_expression, expression )
| symbolic_factor_extended "." field_name "=" expression // workaround: set( symbolic_factor_extended, "field_name", expression )
expression = term { ( "+" | "-" ) term } // left-associative: a op b op c ≡ ( a op b ) op c ( → Wikipedia: de | en )
term = potenz { ( "*" | "/" ) potenz } | simple_term // left-associative (like expression)
simple_term = potenz { [ " " /* blank, if necessary */ ] simple_potenz } // without operator "*" oder "/" (but possibly with sign)
// for symbolic_factor_terminated: single argument without () brackets
potenz = { "-" | "+" } simple_potenz
simple_potenz = factor [ ( "^" | "**" ) potenz ] // without sign for simple_term, (recursive =>) right-associative: a^b^c ≡ a^(b^c)
factor = decimal_constant | symbolic_factor_terminated
decimal_constant = ( digit { digit | "_" } [ "." { digit | "_" } ] | "." { "_" } digit { digit | "_" } ) [ ( "E" | "e" ) [ "-" | "+" ] digit { digit } ]
// without sign, no blanks within a decimal_constant, ".2" and "5." are valid, decimal_constant may contain '_'
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
symbolic_factor_terminated = "@" [ package_path "." ] class_name [ " " /* blank, if necessary */ ] simple_term // constructor call ( "@" in JXN ≡ new in Java)
| "@" simple_term // deprecated
| [ [ package_path "." ] class_name "." ] static_method_name [ " " /* blank, if necessary */ ] simple_term
| symbolic_factor_extended [ "." method_name [ " " /* blank, if necessary */ ] simple_term ]
symbolic_factor_extended = symbolic_factor { "[" [ expression [ ":" [ expression ] ] ] "]" // []-access, left-associative
| "." field_name | "." method_name argument_list } // left-associative
symbolic_factor = variable_name | "(" expression ")" | string_constant | character_constant
| "{" ( comma_separated_expressions | expression ":" expression ) "}" // creates an array
| "@" [ package_path "." ] class_name argument_list // constructor call ( "@" in JXN ≡ new in Java)
| "@" argument_list // deprecated
| [ package_path "." ] class_name "." ( static_field_name | static_method_name argument_list ) // static field access or static method call
| static_method_name argument_list // class defined by first non primitive argument or #import static
| static_field_name // is not supported (=> e.g. E for Math.E is not possible)
variable_name | function_name | parameter_name | class_name | field_name | static_field_name | method_name | static_method_name = identifier
package_path = identifier { "." identifier }
identifier = ? java_identifier_start ? { ? java_identifier_part ? } // no blanks within an identifier, → isJavaIdentifierStart, → isJavaIdentifierPart
string_constant = """ { character } """ // blanks are significant within a string_constant, "" = empty string
character_constant = "'" character "'" // without blanks
character = ? single_character ? | "\"" | "\'" | "\\" | "\0" | "\t" | "\n" | "\r" | "\b" | "\f"
| "\u" hex hex hex hex // without blanks, Unicode ( → Wikipedia: de | en )
| "\#" digit { digit } [";"] // without blanks, Unicode (decimal), ";" may be omitted, if not followed by another digit
hex = digit | "a" | "b" | "c" | "d" | "e" | "f" | "A" | "B" | "C" | "D" | "E" | "F"
argument_list = "(" comma_separated_expressions ")"
comma_separated_expressions = [ expression { "," expression } ] // may be empty
JXN Special Command Syntax (also see JxnScripting)
#filespec.jxn [ simple_term | argument_list ] // filespec may contain blanks
#filespec_without_blanks[.jxn] [ simple_term | argument_list ]
#this [ simple_term | argument_list ] // deprecated
#remove variable_name
#import package_path [ "." class_name ]
#remove [ package ] package_path [ "." class_name ]
#remove [ package ] class_name
#import static [ package_path "." ] class_name
#remove static [ package_path "." ] class_name
the following special commands are available
- only for interactive use from the input line:
#edit [ command ]
#reinit
#exit
- only inside a jxn file (not for interactive use):
#function function_name [ "(" [ parameter_name { "," parameter_name } ] ")" ]
#endfunction
#return [ statement ]
#if statement
#ifdef variable_name
#ifndef variable_name
#else [ if statement ]
#endif
- only inside a #function definition (inside a jxn file):
#while statement
#break
#continue
#endwhile