## EBNF

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

    ; JBehave Grammar expressed in EBNF (http://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_Form)

    ; The story describes a feature via description, narrative and a set of scenarios
    Story := Description? Meta? Narrative? GivenStories? Lifecycle? Scenario+ ;

    ; The Description is expressed by any sequence of words that must not contain any keywords at start of lines.
    Description := (Word Space?)* ;

    ; The meta is identified by keyword "Meta:" (or equivalent in I18n-ed locale),
    ; It is followed by any number of meta elements
    Meta:= "Meta:" (MetaElement)* ;

    ; The meta element is identified by keyword "@" (or equivalent in I18n-ed locale),
    ; It is followed by a name-value pair, where the value can be empty or have multiple words
    MetaElement:= "@" Space? Word Space (Word Space?)* ;

    ; The narrative is identified by keyword "Narrative:" (or equivalent in I18n-ed locale),
    ; It is followed by the narrative elements
    Narrative:= "Narrative:" ( InOrderTo AsA IWantTo | AsA IWantTo SoThat ) ;

    ; The narrative elements
    InOrderTo:= "In order to" NarrativeElementContent ;
    AsA:= "As a" NarrativeElementContent ;
    IWantTo:= "I want to" NarrativeElementContent ;
    SoThat:= "So that" 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" | "So that") ;

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

    ; The lifecycle is identified by keyword "Lifecycle:" (or equivalent in I18n-ed locale),
    ; It is followed by the lifecycle elements
    Lifecycle:= "Lifecycle:" LifecycleBefore? LifecycleAfter?

    ; The before lifecyle element identified by keyword "Before:" (or equivalent in I18n-ed locale),
    ; followed by one or more steps
    LifecycleBefore:= "Before:" (Scope? Step+)+

    ; The after lifecyle element identified by keyword "After:" (or equivalent in I18n-ed locale),
    ; followed by one or more sets of scope, outcome, meta filter and steps
    LifecycleAfter:= "After:" (Scope? Outcome? MetaFilter? Step+)+

    ; The scope element identified by keyword "Scope:" (or equivalent in I18n-ed locale),
    Scope:= "Scope:" "SCENARIO" | "STORY"

    ; The outcome element identified by keyword "Outcome:" (or equivalent in I18n-ed locale),
    Outcome:= "Outcome:" "ANY" | "SUCCESS" | "FAILURE";

    ; The meta filter element identified by keyword "MetaFilter:" (or equivalent in I18n-ed locale),
    MetaFilter:= "MetaFilter:" (Word Space?)*

    ; 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 title, which is expressed by any sequence of words
    ; that must not contain any keywords at start of lines.
    ; 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:"? Title? Meta? GivenStories? Step+ Examples? ;

    ; The free-text description
    Title := (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 story resource path
    StoryPath := PathCharacter+ ;

    ; The characters allowed in a 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 ? ;