Lojban Machine Grammar, EBNF Version, 3rd Baseline as of 10 January 1997

This document is explicitly dedicated to the public domain by its author,
the Logical Language Group Inc.  Contact that organization at:
2904 Beau Lane, Fairfax VA 22031 USA 703-385-0273 (intl: +1 703 385 0273)

Explanation of notation:  All rules have the form:

	name<number> = bnf-expression

which means that the grammatical construct "name" is defined by
"bnf-expression".  The number cross-references this grammar with
the rule numbers in the YACC grammar.  The names are the same as those
in the YACC grammar, except that subrules are labeled with A, B, C, ... in the
YACC grammar and with 1, 2, 3, ... in this grammar.  In addition, rule 971 is
"simple_tag" in the YACC grammar but "stag" in this grammar, because of its
frequent appearance.

1)  Names in lower case are grammatical constructs.
2)  Names in UPPER CASE are selma'o (lexeme) names, and are terminals.
3)  Concatenation is expressed by juxtaposition with no operator symbol.
4)  / represents alternation (choice).
5)  ()? represents an optional element.
6)  & represents and/or ("A / B" is the same as "A / B / A B" / "A B" is the same as "A / B / A B").
7)  ... represents optional repetition of the construct to the left.
    Left-grouping is implied; right-grouping is shown by explicit
    self-referential recursion with no "..."
8)  () serves to indicate the grouping of the other operators.
    Otherwise, "..." binds closer than &, which binds closer than /.
9)  free* is shorthand for "(free+)?", a construct which appears in many places.
10) ()? encloses an elidable terminator, which may be omitted (without change
    of meaning) if no grammatical ambiguity results.


text<0> = (NAI+)? (CMENE+ free* / (indicators / free+ / indicators free+))? (joik-jek)? text-1

text-1<2> = ((I (jek / joik)? ((stag)? BO)? free*)+ / NIhO+ free*)? (paragraphs)?

paragraphs<4> = paragraph (NIhO+ free* paragraphs)?

paragraph<10> = (statement / fragment) (I free* (statement / fragment)?)*

statement<11> = statement-1 / prenex statement

statement-1<12> = statement-2 (I joik-jek (statement-2)?)*

statement-2<13> = statement-3 (I (jek / joik)? (stag)? BO free* (statement-2)?)?

statement-3<14> = sentence / (tag)? TUhE free* text-1 (TUhU free*)?

fragment<20> = ek free* / gihek free* / quantifier / NA free* / terms (VAU free*)? / prenex /
        relative-clauses / links / linkargs

prenex<30> = terms ZOhU free*

sentence<40> = (terms (CU free*)?)? bridi-tail

subsentence<41> = sentence / prenex subsentence

bridi-tail<50> = bridi-tail-1
        (gihek (stag)? KE free* bridi-tail (KEhE free*)? tail-terms)?

bridi-tail-1<51> = bridi-tail-2 (gihek free* bridi-tail-2 tail-terms)*

bridi-tail-2<52> = bridi-tail-3 (gihek (stag)? BO free* bridi-tail-2 tail-terms)?

bridi-tail-3<53> = selbri tail-terms / gek-sentence

gek-sentence<54> = gek subsentence gik subsentence tail-terms /
        (tag)? KE free* gek-sentence (KEhE free*)? / NA free* gek-sentence

tail-terms<71> = (terms)? (VAU free*)?

terms<80> = terms-1+

terms-1<81> = terms-2 (PEhE free* joik-jek terms-2)*

terms-2<82> = term (CEhE free* term)*

term<83> = sumti / (tag / FA free*) (sumti / (KU free*)?) / termset / NA KU free*

termset<85> = NUhI free* gek terms (NUhU free*)? gik terms (NUhUfree*)? /
        NUhI free* terms (NUhU free*)?

sumti<90> = sumti-1 (VUhO free* relative-clauses)?

sumti-1<91> = sumti-2 ((ek / joik) (stag)? KE free* sumti (KEhE free*)?)?

sumti-2<92> = sumti-3 (joik-ek sumti-3)*

sumti-3<93> = sumti-4 ((ek / joik) (stag)? BO free* sumti-3)?

sumti-4<94> = sumti-5 / gek sumti gik sumti-4

sumti-5<95> = (quantifier)? sumti-6 (relative-clauses)? /
        quantifier selbri (KU free*)? (relative-clauses)?

sumti-6<97> = (LAhE free* / NAhE BO free*) (relative-clauses)? sumti (LUhU free*)? /
        KOhA free* / lerfu-string (BOI free*)? / LA free* (relative-clauses)? CMENE+ free* /
        (LA / LE) free* sumti-tail (KU free*)? / LI free* mex (LOhOfree*)? /
        ZO any-word free* / LU text (LIhU free*)? / LOhU any-word+ LEhU free* /
        ZOI any-word anything any-word free*

sumti-tail<111> = (sumti-6 (relative-clauses)?)? sumti-tail-1 /
        relative-clauses sumti-tail-1

sumti-tail-1<112> = (quantifier)? selbri (relative-clauses)? / quantifier sumti

relative-clauses<121> = relative-clause (ZIhE free* relative-clause)*

relative-clause<122> = GOI free* term (GEhU free*)? / NOI free* subsentence (KUhOfree*)?

selbri<130> = (tag)? selbri-1

selbri-1<131> = selbri-2 / NA free* selbri

selbri-2<132> = selbri-3 (CO free* selbri-2)?

selbri-3<133> = selbri-4+

selbri-4<134> = selbri-5
        (joik-jek selbri-5 / joik (stag)? KE free* selbri-3 (KEhE free*)?)*

selbri-5<135> = selbri-6 ((jek / joik) (stag)? BO free* selbri-5)?

selbri-6<136> = tanru-unit (BO free* selbri-6)? / (NAhE free*)? guhek selbri gik selbri-6

tanru-unit<150> = tanru-unit-1 (CEI free* tanru-unit-1)*

tanru-unit-1<151> = tanru-unit-2 (linkargs)?

tanru-unit-2<152> = BRIVLA free* / GOhA (RAhO)? free* / KE free* selbri-3 (KEhE free*)? /
        ME free* sumti (MEhU free*)? (MOI free*)? / (number / lerfu-string) MOI free* /
        NUhA free* mex-operator / SE free* tanru-unit-2 / JAI free* (tag)? tanru-unit-2 /
        any-word (ZEI any-word)+ / NAhE free* tanru-unit-2 /
        NU (NAI)? free* (joik-jek NU (NAI)? free*)* subsentence (KEI free*)?

linkargs<160> = BE free* term (links)? (BEhO free*)?

links<161> = BEI free* term (links)?

quantifier<300> = number (BOI free*)? / VEI free* mex (VEhOfree*)?

mex<310> = mex-1 (operator mex-1)* / FUhA free* rp-expression

mex-1<311> = mex-2 (BIhE free* operator mex-1)?

mex-2<312> = operand / (PEhO free*)? operator mex-2+ (KUhE free*)?

rp-expression<330> = rp-operand rp-operand operator

rp-operand<332> = operand / rp-expression

operator<370> = operator-1
        (joik-jek operator-1 / joik (stag)? KE free* operator (KEhE free*)?)*

operator-1<371> = operator-2 / guhek operator-1 gik operator-2 /
        operator-2 (jek / joik) (stag)? BO free* operator-1

operator-2<372> = mex-operator / KE free* operator (KEhE free*)?

mex-operator<374> = SE free* mex-operator / NAhE free* mex-operator /
        MAhO free* mex (TEhU free*)? / NAhU free* selbri (TEhUfree*)? / VUhU free*

operand<381> = operand-1 ((ek / joik) (stag)? KE free* operand (KEhE free*)?)?

operand-1<382> = operand-2 (joik-ek operand-2)*

operand-2<383> = operand-3 ((ek / joik) (stag)? BO free* operand-2)?

operand-3<385> = quantifier / lerfu-string (BOI free*)? /
        NIhE free* selbri (TEhU free*)? / MOhE free* sumti (TEhUfree*)? /
        JOhI free* mex-2+ (TEhU free*)? / gek operand gik operand-3 /
        (LAhE free* / NAhE BO free*) operand (LUhU free*)?

number<812> = PA (PA / lerfu-word)*

lerfu-string<817> = lerfu-word (PA / lerfu-word)*

lerfu-word<987> = BY / any-word BU / LAU lerfu-word / TEI lerfu-string FOI

ek<802> = (NA)? (SE)? A (NAI)?

gihek<818> = (NA)? (SE)? GIhA (NAI)?

jek<805> = (NA)? (SE)? JA (NAI)?

joik<806> = (SE)? JOI (NAI)? / interval / GAhO interval GAhO

interval<932> = (SE)? BIhI (NAI)?

joik-ek<421> = joik free* / ek free*

joik-jek<422> = joik free* / jek free*

gek<807> = (SE)? GA (NAI)? free* / joik GI free* / stag gik

guhek<808> = (SE)? GUhA (NAI)? free*

gik<816> = GI (NAI)? free*

tag<491> = tense-modal (joik-jek tense-modal)*

stag<971> = simple-tense-modal ((jek / joik) simple-tense-modal)*

tense-modal<815> = simple-tense-modal free* / FIhO free* selbri (FEhU free*)?

simple-tense-modal<972> = (NAhE)? (SE)? BAI (NAI)? (KI)? /
        (NAhE)? ((time (space)? / space (time)?) / CAhA / (time (space)? / space (time)?) CAhA) (KI)? / KI / CUhE

time<1030> = ZI (time-offset+)? (ZEhA (PU (NAI)?)?)? (interval-property+)? / (ZI)? time-offset+ (ZEhA (PU (NAI)?)?)? (interval-property+)? / (ZI)? (time-offset+)? ZEhA (PU (NAI)?)? (interval-property+)? / (ZI)? (time-offset+)? (ZEhA (PU (NAI)?)?)? interval-property+

time-offset<1033> = PU (NAI)? (ZI)?

space<1040> = VA (space-offset+)? (space-interval)? ((MOhI space-offset))? / (VA)? space-offset+ (space-interval)? ((MOhI space-offset))? / (VA)? (space-offset+)? space-interval ((MOhI space-offset))? / (VA)? (space-offset+)? (space-interval)? (MOhI space-offset)

space-offset<1045> = FAhA (NAI)? (VA)?

space-interval<1046> = (((VEhA / VIhA / VEhA VIhA) (FAhA (NAI)?)?) / space-int-props / ((VEhA / VIhA / VEhA VIhA) (FAhA (NAI)?)?) space-int-props)

space-int-props<1049> = (FEhE interval-property)+

interval-property<1051> = number ROI (NAI)? / TAhE (NAI)? / ZAhO (NAI)?

free<32> = SEI free* (terms (CU free*)?)? selbri (SEhU)? / SOI free* sumti (sumti)? (SEhU)? /
        vocative (relative-clauses)? selbri (relative-clauses)? (DOhU)? /
        vocative (relative-clauses)? CMENE+ free* (relative-clauses)? (DOhU)? /
        vocative (sumti)? (DOhU)? / (number / lerfu-string) MAI /
        TO text (TOI)? / XI free* (number / lerfu-string) (BOI)? /
        XI free* VEI free* mex (VEhO)?

vocative<415> = (COI (NAI)?)+ & DOI

indicators<411> = (FUhE)? indicator+

indicator<413> =  (UI / CAI) (NAI)? / Y / DAhO / FUhO


The following rules are non-formal:

word<1100> = (BAhE)? any-word (indicators)?

any-word = "any single word (no compound cmavo)"

anything = "any text at all, whether Lojban or not"
null<1101> = any-word SI / utterance SA / text SU

FAhO is a universal terminator and signals the end of parsable input.
