EBNF

Below is a detailed outlay of the grammar JBehave understands. It is expressed in EBNF.

; The story describes a feature via a narrative (optional) and a collection of scenarios
Story := Narrative? Scenario+ ;

; The narrative is identified by keyword "Narrative:" (or equivalent in I18n-ed locale),
; It can optionally be followed by a description, which is expressed by any sequence of words
; that must not contain any keywords.
; It is followed by the narrative elements
Narrative:= "Narrative:" Description? InOrderTo AsA IWantTo ;

; The narrative elements
InOrderTo:= "In order to" NarrativeElementContent ;
AsA:= "As a" NarrativeElementContent ;
IWantTo:= "I want to" NarrativeElementContent ;

; The narrative element content is any sequence of characters that do not match a narrative starting word
NarrativeElementContent := ? Any sequence of NarrativeCharacter that does not match NarrativeStartingWord ? ; 

; All characters are allowed in a narrative content, including newlines
NarrativeCharacter := ? Any Unicode character ? ;

; The narrative starting words (or equivalent in I18n-ed locale)
NarrativeStartingWord :== ("In order to" | "As a" | "I want to" ) ;

; The scenario is identified by keyword "Scenario:" (or equivalent in I18n-ed locale),
; which is optional in the case of a single scenario.  
; It can optionally be followed by a description, which is expressed by any sequence of words
; that must not contain any keywords.
; It is followed by one or more Steps. 
; Finally the optional Examples table, which if present will execute the scenario for as many table rows present
Scenario := "Scenario:"? Description? GivenStories? Step+ Examples? ;

; The free-text description 
Description := (Word Space?)* ;

; The word is any sequence of non-space characters that does not match a KeyWord
Word := ? Any sequence of NonSpaceCharacter that does not match KeyWord ? ;

; The space character
Space := ? Unicode space character ? ;

; The non-space character
NonSpaceCharacter := ? Any Unicode character except Space ? ;

; The keywords which are reserved (or equivalent in I18n-ed locale)
KeyWord := "Scenario:" | "GivenStories:" | "Given" | "When" | "Then" | "And" | "!--";

; The comma-separated list of story resources that specify the stories to be run before the scenario steps
GivenStories:= "GivenStories:" (StoryResourcePath ','?)+ ;

; The story resource path
StoryResourcePath := PathCharacter+ ;

; The characters allowed in a scenario resource path
PathCharacter := "/" | "." | "_" | Letter | Digit ;

; The letter characters
Letter := ? Any Unicode letter character ? ;

; The digit characters
Digit := ? Any Unicode digit character ? ;

; The scenario step is a step starting work followed by any number of characters
Step := StepStartingWord StepContent ;

; The step starting words (or equivalent in I18n-ed locale)
StepStartingWord :== ("Given" | "When" | "Then" | "And" | "!--") ;

; The step content is any sequence of characters that do not match a step starting word
StepContent := ? Any sequence of StepCharacter that does not match StepStartingWord ? ; 

; All characters are allowed in a scenario step content, including newlines
StepCharacter := ? Any Unicode character ? ;

; The examples table
Examples := "Examples:" ExamplesTable ;

; The examples table comprises of a header row and data rows
ExamplesTable := ExamplesTableHeader ExamplesTableRow+ ;

; The examples table header contains the column names, separated by ExamplesTableColumnSeparator
ExamplesTableHeader := ((ExamplesTableColumnSeparator ExamplesTableCharacter+)+ ExamplesTableColumnSeparator  Newline ;

; The examples table row contains the column values, separated by ExamplesTableColumnSeparator
ExamplesTableRow := ((ExamplesTableColumnSeparator ExamplesTableCharacter+)+ ExamplesTableColumnSeparator  Newline ;

; The examples table character can be any character, expect for ExamplesTableColumnSeparator and Newline
ExamplesTableCharacter := ? Any Unicode character except ExamplesTableColumnSeparator and Newline ? ;

; The examples table column separator
ExamplesTableColumnSeparator := "|" ;

; The new line character
Newline := ? Unicode newline character ? ;