2015-06-19 3 views
0

Я использую JavaCC для создания спецификации для распознавания языка. Проблема в том, что JavaCC дает мне предупреждение, потому что public является общим префиксом объявления Member(). Member() может иметь атрибуты() и/или метод(), но должен иметь хотя бы один метод, порядок не имеет значения.Избегайте распространенных префиксов без изменений lookahead

Предупреждение JavaCC дает мне это:

Выбор конфликт (...) + построить в строке 66, столбец 23. расширения вложен в конструкта и расширения следующие конструкции имеют общие префиксы, один из которых является: «общественность». Подумайте о том, как использовать 2 или более для вложенного расширения.

Линия 66 является единственной строкой члена(). Также мне нужно сделать это без изменения смотрового значения.

Вот код:

void Member() : {} 
    { 
     (Attribute())* (Method())+ (Attribute() | Method())* 
    } 

void Attribute() : {} 
    { 
     "private" Type() <Id> [":=" Expr()]";" 
    } 

void Method() : {} 
    { 
     MethodHead() MethodBody() 
    } 

void MethodHead() : {} 
    { 
     ("public")? (<Id> | Type() | "void") <Id> "(" Parameter() ")" 
    } 

Спасибо.

ответ

0

Проблема заключается в том, что это регулярное выражение

(Method())+ (Attribute() | Method())* 

неоднозначно. Давайте сократим методы с помощью M и атрибутов на A. Если вход MAM, нет проблем. (Method())+ соответствует первому M, а (Attribute() | Method())* соответствует оставшемуся AM. Но если вход MMA, где должен быть деление? Либо (Method())+ соответствует M, так и (Attribute() | Method())* соответствует MA или (Method())+ соответствует MM и (Attribute() | Method())* соответствует А. Оба анализа могут быть выполнены. JavaCC не знает, какой синтаксический анализ вы хотите, поэтому он жалуется.

Что вы можете сделать:

  • Ничего. Игнорировать предупреждение. Поведение по умолчанию заключается в том, что как можно больше методов будет распознано (Method())+, и только методы после первого атрибута будут распознаны (Attribute() | Method())*.
  • Подавление предупреждения с помощью lookahead. Вы сказали, что не хотите добавлять lookahead, но для полноты я упомянул, что вы могли бы изменить (Method())+ на (LOOKAHEAD(1) Method())+. Это не изменит поведение анализатора, но оно подавит предупреждение.
  • Перепишите грамматику.

Нарушитель линия может быть переписано в виде либо

(Attribute())* Method() (Attribute() | Method())* 

или

(Attribute())* (Method())+ [Attribute() (Attribute() | Method())*] 
+0

Спасибо. Он работал, удаляя «+» из метода(). Большое спасибо. – apeiron

Смежные вопросы