Я бы сохранял грамматику лексера настолько простой, насколько это возможно, и просто сопоставлял бы ноль или более пробелов, за которыми следовал бы необязательный знак, за которым следовал бы номер в вашей грамматике синтаксического анализатора. После сопоставления, проверьте (в вашей грамматике синтаксического анализатора), правильна ли "ширина" поля.
Пример грамматики:
line
: field ('|' field)*
;
field
: Spaces? ('+' | '-')? Number // validate if 'field' is correct in this rule
;
Number
: '0'..'9'+
;
Spaces
: ' '+
;
И возможная схема проверки может выглядеть так:
line
: field ('|' field)*
;
field
@init{int length = 0;}
: (Spaces {length += $Spaces.text.length();})?
('+' | '-')? Number {length += $Number.text.length(); if(length != 4) {/* do something */}}
;
Number
: '0'..'9'+
;
Spaces
: ' '+
;