Introduction

Definition: A grammar is a description of an edi-message.
A grammar describes the records, fields, formats etc of an edi file.
Bots uses grammars to parse, check and generate edi files.
Grammars files are independent of the editype: a grammar for a csv files looks the same as a grammar for a x12 file.
Grammar files are in: usersys/grammars/editype/grammar name.py

Learn grammar by example

Best way to get the idea of a grammar is to look at the (simple) example in the chapter.

This CSV file:

HEADER,ordernumber1,buyer1,20120524
LINE,1,article1,24,description1
LINE,2,article2,288,
LINE,3.article3,6,description3

has this grammar:

from bots.botsconfig import *        #always needed

syntax = {                           #'syntax' section
'field_sep' : ',',               #specify field separator
'charset'   : 'utf-8',           #specify character-set
}

structure = [                        #'structure' section
{ID:'HEADER',MIN:1,MAX:999,LEVEL:[   #each order starts with a HEADER record
{ID:'LINE',MIN:1,MAX:9999},      #nested under the HEADER record are the LINE records, repeat up to 9999 times
]}
]

recorddefs = {                       #'recorddefs' section
'HEADER':[                           #specify the fields in the HEADER record
['BOTSID','M',6,'A'],            #BOTSID is for the HEADER tag itself
['order number', 'M', 17, 'AN'], #for each field specify the format, max length, M(andatory) or C(onditional)
['buyer ID', 'M', 13, 'AN'],
['delivery date', 'C', 8, 'AN'],
],
'LINE':[
['BOTSID','M',6,'A'],
['line number', 'C', 6, 'N'],
['article number', 'M', 13, 'AN'],
['quantity', 'M', 20, 'R'],
['description', 'C', 70, 'R'],
],
}

The example above is simple, but fully functional.

Sections of a grammar

A grammar file consists of these sections:

  • syntax: parameters for the grammar like field separator, merge or not, indent xml, etc.
  • structure: sequence of records in an edi-message: start-record, nested records, repeats.
  • recorddefs: fields per record.
  • nextmessage: to split up an edi file to separate messages.
  • nextmessageblock: to split up a cvs-file to messages.

A section can be reused/imported from another grammar file.
Purpose: better maintenance of grammars.
Example: edifact messages from a certain directory use the same recorddefs/segments:

 from recordsD96AUN import recorddefs

One edifact grammar consists of four parts. Example:

  • edifact.py (contains syntax common to all edifact grammars)
  • envelope.py (contains envelope structure and recorddefs common to all edifact grammars)
  • recordsD96AUN.py (contains recorddefs common to all edifact D96A grammars)
  • ORDERSD96AUN.py (contains structure specifically for ORDERS D96A)

Problems for some edifact grammars on sourceforge site

Sometimes you might meet this error for a grammar:

GrammarError: Grammar "...somewhere...", in structure: nesting collision detected at record "etc etc". This is the case eg with INVRPT D96A.
UN says about this that you have to make additional choices in message; either you make some segments mandatory or leave out some segment groups.
EANCOM did make such choices in their implementation guidelines.
So: you can not use the grammar directly, edit it according to your needs. This is according to what UN-edifact wants...