// PROGRAM

t.Syntax ::= t.Module | t.Interface

t.Module ::= (MODULE t.Pragma t.Name e.Body)

t.Interface ::= (INTERFACE t.Pragma t.Name e.Body)

e.Body ::= [Empty] | e.ModuleBody t.Item 

t.Item ::= t.Function | t.Object | t.Const

s.Linkage ::= s.IntLinkage | s.ExtLinkage
s.IntLinkage ::= EXPORT | LOCAL
s.ExtLinkage ::= IMPORT

t.Function ::= (FUNC t.Pragma s.IntLinkage s.FunctionTag t.Name t.Format t.Format t.Sentence)
             | (FUNC t.Pragma s.ExtLinkage s.FunctionTag t.Name t.Format t.Format)
s.FunctionTag ::= FUNC | FUNC?


t.Object ::= (OBJECT t.Pragma s.Linkage s.ObjectType t.Name)
s.ObjectType ::= TABLE | BOX | STRING | VECTOR | CHANNEL

t.Const ::= (CONST t.Pragma s.Linkage t.Name t.ConstExpression)

// new:
t.Value ::= (VALUE t.Pragma s.Linkage t.Name t.ResultExpression)
t.Initializer ::= (EXEC e.ResultExpression)

// SENTENCE

e.Sentences ::= [Empty] | t.Sentence e.Sentences

t.Sentence ::= (BRANCH t.Pragma e.Statements) 

e.Statements ::= [Empty] | t.Statement e.Statements

t.Statement ::= t.Action | t.Operator | t.ComplexOperator

t.Action ::= t.Alt | t.Pattern | t.Result | t.Format

t.Alt ::= (ALT t.Pragma s.type e.Sentences)
s.type ::= FAIL | NOFAIL

t.Pattern ::= (PATTERN t.Pragma s.Direction t.PatternExpression)
s.Direction ::= LEFT | RIGHT

t.Result ::= (RESULT t.Pragma t.ResultExpression) 

t.Format ::= (FORMAT t.Pragma t.HardExpression)

t.Operator ::= (CUT    t.Pragma)
             | (CUTALL t.Pragma)
             | (STAKE  t.Pragma)
             | (FAIL   t.Pragma)
             | (NOFAIL t.Pragma)

t.ComplexOperator ::= (NOT   t.Pragma t.Sentence)
                    | (ERROR t.Pragma t.Sentence)
                    | (ITER  t.Pragma t.Sentence t.HardExpression)
                    | (TRY   t.Pragma t.Sentence t.Sentence)

// EXPRESSION

t.ConstExpression   ::= t.Expression  // without call, vars
t.HardExpression    ::= t.Expression  // without call and two or more soft variables on same level in one brackets
t.PatternExpression ::= t.Expression  // without call
t.ResultExpression  ::= t.Expression

t.Expression ::= (EXPR t.Pragma e.Terms)

e.Terms ::= [Empty] | t.Term e.Terms

t.Term ::= t.Symbol | t.Paren | t.Variable | t.Call

t.Paren ::= (PAREN t.Pragma t.Expression) 

t.Call ::= (CALL t.Pragma t.Name t.Expression)

t.Symbol ::= (SYMBOL t.Pragma e.Data) | (REF t.Pragma t.Name)

t.Variable ::= (VAR t.Pragma s.VarType t.Name) | (VAR t.Pragma s.VarType)

s.VarType ::= E | V | T | S

// NAME

t.Name ::= (NAME t.Pragma e.QualifiedName)

e.QualifiedName ::= [Word] | [Word] e.QualifiedName

// PRAGMA

t.Pragma ::= (PRAGMA e.PragmaBody)

e.PragmaBody ::= [Empty] | t.PragmaTerm e.PragmaBody

t.PragmaTerm ::= (FILE e.FileName)
               | (LINE s.Line s.Column)
               | (TRACE e.TraceNames)
               | ...

e.FileName ::= [Sequence of liters]

s.Line ::= [Number]

s.Column ::= [Number]

e.TraceNames ::= [Empty] | t.Name e.TraceNames
