Delimited lists like (a; b; c) often appear in programs, for example when specifing parameters of a function. In order to indentify errors is such lists you can use the LR grammar (eg. bison/flex):
Identifier_List :
TKLP TKRP { cout << "(empty list)" << endl; }
| TKLP Sep_Simple_List Item TKRP { cout << "(last list item)" << endl; }
| TKLP Sep_Simple_List error TKRP { cout << "(ERROR in last item)" << endl; }
;
Sep_Simple_List :
Sep_Simple_List Item Sep { cout << "(non-last list item)"; }
| Sep_Simple_List error Sep { cout << "(ERROR in non-last item)"; }
| { cout << "(empty sep_list)"; }
;
Item : TKIDENTIFIER;
Sep: TKSEMI;
To obtain a LL grammar (eg.
ANTLR) you need to do some transformations since left-recursive rules like (a::=a b | b) are not allowed.