Являются ли грамматики C # и Java LALR (x)? - PullRequest
17 голосов
/ 05 декабря 2011

Интересно, грамматики C # и Java LALR (x)?Если да, каково значение х?

Редактировать:

После принятия верного ответа, я думаю, что лучше изменить Q следующим образом:

Есть ли LALR (х) синтаксический анализатор, который может анализировать текущие выпуски Java (версия 7) или C # (версия 4)?Если да, каково значение х?

Ответы [ 3 ]

14 голосов
/ 05 декабря 2011

Вы не можете задать этот вопрос, предварительно не назначив определенную грамматику для языка, как могут быть некоторые грамматики, а некоторые нет.

Возможно, вы имеете в виду грамматику Java, опубликованную в последних спецификациях Java.Вы имеете в виду Java 7?

Я не уверен, что вы можете назначить конкретную грамматику для C #, по крайней мере, для Microsoft, особенно для C # 4.0;Я не верю, что они опубликовали грамматику.

Я могу вам сказать, что я не думаю, что C # может быть LALR (x), потому что в нем есть некоторые элементы, которые выглядят как идентификаторы, но могут быть ключевыми словами вопределенные контексты.Это требует, чтобы лексер знал, что синтаксический анализатор ожидает, чтобы решить, является ли маркер, подобный идентификатору, ключевым словом, или просто и идентификатором.Таким образом, должна быть обратная связь от парсера к лексеру, или лексер должен произвести оба токена и передать их парсеру, чтобы решить, какой он хочет.Синтаксические анализаторы LALR определяются в потоках токенов без обратной связи, и где каждый входной токен имеет только одну интерпретацию.

Я не думаю, что Java тоже от Java 1.5 и выше, когда enum был представлен как специальный тип со своим собственным ключевым словом.Это связано с тем, что для компиляторов Java 1.5 для обработки существующих программ на Java 1.4, которые использовали enum в качестве имени переменной, enum в некоторых контекстах должны рассматриваться как ключевое слово и как имя переменнойв других.Таким образом, синтаксический анализатор Java 1.5 имеет те же проблемы, что и C #.

На практике нет реальных языков LALR (1) [первое издание Java может быть исключением], и любой, кто создает настоящий анализатор (особенно LALR)) должен сделать какой-то хак, чтобы обойти это.(GCC лихо анализировал C ++ с помощью анализатора LALR с ужасным взломом таблицы символов, поэтому он мог отличить идентификатор как переменную от идентификатора как экземпляр typedef. Теперь он имеет своего рода ручную реализациюпарсер рекурсивного спуска, но я думаю, что ужасный взлом остается).Поэтому я не уверен, стоит ли отвечать на ваш вопрос.

Наши C # 4.0 и Java 7 члены нашего семейства языковых интерфейсов оба анализируют языки с помощью расширенного синтаксического анализатора GLRкак с возможностью обратной связи, так и с возможностью обрабатывать две интерпретации одного и того же токена.РВО делает вопрос LALR (х) тоо, а обратная связь и множественные интерпретации позволяют нам обрабатывать множество языков, которые были бы вне чистой способности РВО, тоже

1022 * EDIT:. После того, как немного мысли, что может бытьдействительно уродливый способ заставить обе грамматики обрабатывать свои ключевые слова в контексте.Давайте использовать перечисление Java в качестве примера.Реально должно быть правило грамматики:
  type = 'enum' '{'  enum_members '}' ;

Но нам также нужно разрешить 'enum' в качестве идентификатора.Мы можем сделать это, заменив маркер терминала идентификатор на нетерминал:

  identifier = IDENTIFIER | 'enum' ;

и настаивая на том, что ИДЕНТИФИКАТОРЫ являются терминалами, созданными лексером.Теперь, по крайней мере, лексеру не нужно решать, как лечить enum ;парсер делает.Но ваша назначенная грамматика должна была бы иметь такую ​​форму, чтобы даже иметь шанс быть LALR (x).

Наши парсеры делали это, чтобы иногда использовать некоторые ключевые слова в качестве идентификаторов.Мы изменили наш механизм синтаксического анализа, как описано ранее, и больше не делаем этого.

13 голосов
/ 05 декабря 2011

Грамматика Java (версия 1.0) известна как LALR (1); этот сайт предоставляет грамматику и начинается с уведомления о том, что

Грамматика была проверена механически, чтобы убедиться, что она LALR (1).

Я не уверен, является ли C # LALR (1), но здесь доступен C # синтаксический анализатор, написанный на bison, который предполагает, что это, вероятно, LALR (1) (при условии, что вы разрешаете декларации предшествования)).

Для чего стоит, обычно LALR (1) - единственный используемый анализатор LALR.Если вам нужно использовать что-то вроде LALR (2) для грамматики, обычно лучше использовать синтаксический анализатор LALR (1) с явным устранением неоднозначности приоритетов или более мощный анализатор, такой как анализатор GLR.

Надеюсь, это поможет!

4 голосов
/ 05 декабря 2011

По крайней мере, для Java (версия 1.0): http://java.sun.com/docs/books/jls/first_edition/html/19.doc.html

...