Я пробовал несколько разных генераторов парсеров (Bison, DParser и т. Д.), Которые утверждают, что могут генерировать парсеры GLR, то есть те, которые могут обрабатывать неоднозначные грамматики. Вот очень простая двусмысленная грамматика того типа, о котором я говорю:
START: A | B;
A: C | D;
B: C | D;
C: T1 | T2;
D: T3 | T4;
T1: 't1';
T2: 't2';
T3: 't3';
T4: 't4';
Я могу сгенерировать парсеры нормально, но получаю ошибки «неразрешенной неоднозначности» или просто вылетаю, когда я даю парсеру входные данные, которые должны быть действительными. При изменении грамматики на однозначную версию никаких проблем не возникает.
Что я не понимаю в парсерах GLR? Я думал, что все дело в том, что в случаях двусмысленности отслеживаются ВСЕ возможные синтаксические разборы, пока они не сливаются или не заходят в тупик. Все, что мне нужно, это синтаксический анализатор, который может сказать мне, есть ли ЛЮБОЙ допустимый синтаксический анализ ввода.
Спасибо за любую помощь.
редактировать:
Это расстраивает. Используя% dprec и% merge, я смог заставить Bison обрабатывать неоднозначные правила и терминалы, но он по-прежнему подавляется очень простыми, но крайне патологическими псевдоанглийскими грамматиками того типа, с которым мне нужно работать:
S: NP VP | NPA VP;
NPA: D N | NP PP;
NP: D N | NP PP | NPA;
VP: V NP | VP PP;
PP: P NP;
D: "the" | "a";
P: "in" | "with";
V: "saw";
N: "saw" | "girl" | "boy" | "park" | "telescope";
При вводе «мальчик увидел девочку» Bison не может выполнить синтаксический разбор и возвращает код 1. Том, с другой стороны, безупречно справляется с этой грамматикой и этим вводным предложением и даже естественно обрабатывает неизвестные терминалы, просто назначая их всем возможным типы терминалов. Но в отличие от Бизона, Том подавляется большими грамматиками. (Под "дросселированием" я подразумеваю отказы по-разному. Если режимы отказа могут быть полезны, я могу сообщить о них.)
У кого-нибудь есть другие идеи?