2012-04-25 3 views
3

Я не могу понять, что означает синтаксис на C99. Здесь, говоря C99, я имею в виду ISO/IEC 9899: 1999. Ну, я думаю, что синтаксическая часть грамматики не сильно меняется с тех пор, как ANSI C, C89.Как понять C99 стандартный синтаксис

Возьмем для примера из this question:

6.5.5 Multiplicative operators 
    Syntax 
    multiplicative-expression: 
     cast-expression 
     multiplicative-expression * cast-expression 
     multiplicative-expression/cast-expression 
     multiplicative-expression % cast-expression 

    Constraints 

Each of the operands shall have arithmetic type. The operands of the % operator 
shall have integer type. 

    Semantics 

The usual arithmetic conversions are performed on the operands. 
The result of the binary * operator is the product of the operands. 
The result of the/operator is the quotient 

Интересно, почему в синтаксисе мультипликативных операторов мы имеем «литую-выражение»? И какая грамматика может означать этот синтаксис? В that question @Avi сказал, что в

a*b*c 

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

Возьмем другой пример из c99 6.6.1, синтаксис постоянных выражений

Syntax 
    constant-expression: 
     conditional-expression 

почему это условное выражение приходят сюда? Может ли кто-нибудь показать мне, как объяснить этот синтаксис? Спасибо всем заранее.

ответ

3

Интересно, почему в синтаксисе мультипликативных операторов у нас есть «выражение-литье»?

Это типичное устройство, используемое в контекстно-свободной грамматике, чтобы указать группировку операторов с одинаковым приоритетом и указать приоритет в первую очередь (КИ, это не является точным, грамматика может выразить больше, чем просто присваивая приоритет операторам, но если бы мы хотели выразить простое выражение оценки на основе приоритетов в CFG, мы сделали бы это именно так). cast-expression не имеет отношения к multiplicative-expression; это просто «любое выражение, не содержащее мультипликативных операций или операций с более низким приоритетом».

Итак, как это будет работать:

  1. Группировка операторов в тот же очередностью:

    1*2*3*4 
    

    в этом случае имеются следующие возможности для группировки (верхний уровень только):

    • 1*(2*3*4)
    • (1*2)*(3*4)
    • (1*2*3)*4

    , глядя на грамматике, мы знаем, что стоит слева от * должна быть cast-expression, то есть, не должен содержать() * заключённых в скобках. Таким образом, существует только третий альтернативный вариант

  2. Прежний.Представьте выражение

    a*b+c 
    

    Это может быть проанализирован или как

    • (a*b)+c
    • a*(b+c)

    Однако мы знаем, что cast-expression на правой стороне не может содержать (unparenthesized) + (или мы можем это исправить из грамматики, если мы проверим его). Это оставляет первый вариант в качестве единственной возможной альтернативы.

    Другое выражение

    a+b*c 
    

    может быть, в свою очередь, обрабатывается как

    • (a+b)*c
    • a+(b*c)

    Однако multiplicative-expression слева от * не может содержать (unparenthesize d) + либо (в качестве упражнения для читателя). Поэтому существует только вторая альтернатива.

На ваш вопрос об условно-выражения: правила грамматики просто запрещает что-либо эквивалентное или ниже операторов присваивания быть разобрано как constant-expression с. Поэтому a=b, a,b, a+=b не могут быть постоянными выражениями, тогда как a+b, a[b] и a(b) возможно могут. Обратите внимание, что это не запрещает, например. (a=b); вам нужно посмотреть на фактическое предложение, определяющее, что такое постоянные выражения, которые ограничивают область константных выражений больше, чем грамматику.

+0

Я вижу, что если мы просто принимаем 'cast-expression' как некоторое выражение, не являющееся« мультипликативным-выражением », то мы можем знать ассоциативность мультипликативного выражения. Но само литье-выражение имеет синтаксис в c99 '6.5.4.1', нам не нужно гарантировать, что 'c' в выражении примера является' cast-expression'? Можете ли вы немного рассказать о части «условного выражения»? –

+0

Это означает, что мы можем просто изменить выражение 'cast-expression' на' условное выражение'? –

+0

Операторы трансляции просто представляют собой ряд операторов с одним приоритетом выше мультипликативных операторов. Таким же образом строится глава стандартного приоритета оператора. Да, это довольно непонятно и запутанно, как и вся глава относительно выражений в стандарте. – Lundin

1

Интересно, почему в синтаксисе мультипликативных операторов у нас есть «литье-выражение»?

Начнем с гораздо более простой проблемы и, соответственно, более простой грамматики. Мы определим грамматику для представления простого арифметического выражения (1 + 2, 3 * (4 - 2), 42 и т. Д.). Так как мы хотим простой числовой константой, чтобы быть юридическим выражением, мы должны определить нашу грамматику таким образом, что существует путь от корня нетерминальный выражения к простому числа:

 
expression: 
    term | 
    term add-op expression 

term: 
    factor | 
    factor mul-op term 

factor: 
    number | 
    (expression) 

нетерминалы как номер, add-op, и mul-op должно быть очевидно.

42 является номера, который является производством фактора, который является производством термина, который является производством экспрессии.Таким образом, 42 является законным арифметическим выражением в соответствии с нашей грамматикой; термин и Фактор являются промежуточными продуктами на этом пути.

Подобная вещь происходит в грамматике С. A cast-expression является промежуточным производством между выражением и некоторым терминалом, таким как идентификатор или числовая константа. Наша простая грамматика определяет два уровня приоритета; грамматика C определяет 16 различных уровней приоритета с лодкой большего числа операторов, поэтому на этом пути существует намного более промежуточное производство. И мы хотим монолитно-выражение иметь более высокий уровень приоритета, чем мультипликативной экспрессии таким образом мы можем рассматривать дела как

x = a * (int) b; 

должным образом.

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