如何理解C99标准语法

时间:2012-04-25 13:05:22

标签: c c99 iso

我无法理解C99中的语法含义。这里说C99我的意思是ISO / IEC 9899:1999。好吧,我认为语法语法部分自ANSI C,C89以来没有太大变化。

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 

我想知道为什么在乘法运算符的语法中我们有一个" cast-expression" ?这句语法意味着什么语法?在that question @Avi说

a*b*c

" c必须被解析为一个演员表达式",我无法理解这一点。

从c99 6.6.1中获取另一个例子,常量表达式的语法

Syntax
   constant-expression:
       conditional-expression

为什么这个条件表达式出现在这里? 有人可以告诉我如何解释这些语法吗?谢谢大家。

2 个答案:

答案 0 :(得分:3)

  

我想知道为什么在乘法运算符的语法中我们有一个“cast-expression”?

这是在上下文无关语法中使用的典型设备,用于指定相同优先级的运算符的分组,并首先指定优先级(好的,这不精确;语法可以表达的不仅仅是分配优先级对于运算符,但如果我们只想在CFG中表达基于简单优先级的表达式求值,我们就会这样做)。无论如何cast-expressionmultiplicative-expression无关;它只是“任何不包含乘法运算或低优先级运算的表达式”。

那么,这将如何运作:

  1. 同一优先级运算符的分组:

    1*2*3*4
    

    在这种情况下,有以下分组的可能性(仅限顶级):

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

    通过查看语法,我们知道*左边的任何内容必须是cast-expression,也就是说,不得包含(未加括号){{1} }。因此,只有第三种选择是可行的

  2. 优先顺序。想象一下表达式

    *

    可以将其解析为

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

    但是,我们知道右侧的a*(b+c)不能包含(不加括号)cast-expression(或者如果我们检查它,我们可以从语法中解决这个问题)。这使得第一种选择成为唯一可能的选择。

    另一个表达

    +
    反过来,

    可以解析为

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

    但是,a+(b*c)左侧的multiplicative-expression也不能包含(不加括号)*(左侧作为读者的练习)。因此,只有第二种选择是可行的。

  3. 关于条件表达式的问题:语法规则只是禁止将任何等价或低于赋值运算符解析为+ s。因此,constant-expressiona=ba,b不一定是常量表达式,而a+=ba+ba[b]可能是。请注意,它不允许例如。 a(b);你必须查看实际的子句,指定什么是常量表达式,这限制了常量表达式的领域而不是语法。

答案 1 :(得分:1)

  

我想知道为什么在乘法运算符的语法中我们有一个“cast-expression”?

让我们从一个更简单的问题开始,以及相应简单的语法。我们将定义一个语法来表示一个简单的算术表达式(1 + 23 * (4 - 2)42等。由于我们希望普通的数字常量是一个合法的表达式,我们必须定义我们的语法,以便存在从根非终端表达式到简单的数字的路径:

expression:
    term  |
    term add-op expression

term:
    factor |
    factor mul-op term

factor:
    number |
    ( expression ) 

number add-op mul-op 等非终端应该是显而易见的。

42是一个数字,它是 factor 的产生,它是 term 的产生,它是一个生成表达式。因此,根据我们的语法,42是一个合法的算术表达式; term factor 是此路径中的中间作品。

C语法中也发生了类似的事情。 cast-expression 表达式与某些终端(如标识符或数字常量)之间的中间产品。我们的简单语法定义了2个优先级; C语法定义了16个不同级别的优先级,其中包含更多运算符,因此沿着该路径有更多的中间产品。我们希望 cast-expression 具有比 multiplicative-expression 更高的优先级,因此我们可以处理像

这样的情况
x = a * (int) b;

正确。