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
JXN Syntax
JXN Special Commands
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(s) 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
| variable_name ( "+=" | "-=" | "*=" | "/=" | "%=" | "^=" ) expression // (Wikipedia: → augmented assignment)
// jxn handles variable_name op= expression as a syntactical shortcut of variable_name = variable_name op ( expression )
// 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 [ argument_list | expression ] // filespec may contain blanks
#filespec_without_blanks[.jxn] [ argument_list | expression ]
#this [ argument_list | expression ] // 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