规范

每个步骤结尾的 规范 一节都会对这个步骤中的新特性给出规范,方便大家查阅。

step11 语法规范

灰色部分表示相对上一节的修改。


program
    : (function | declaration)*

function
    : type Identifier '(' parameter_list ')' (compound_statement | ';')

type
    : 'int'
| type '*'
parameter_list : (type Identifier (',' type Identifier)*)? compound_statement : '{' block_item* '}' block_item : statement | declaration statement : 'return' expression ';' | expression? ';' | 'if' '(' expression ')' statement ('else' statement)? | compound_statement | 'for' '(' expression? ';' expression? ';' expression? ')' statement | 'for' '(' declaration expression? ';' expression? ')' statement | 'while' '(' expression ')' statement | 'do' statement 'while' '(' expression ')' ';' | 'break' ';' | 'continue' ';' declaration : type Identifier ('=' expression)? ';' expression_list : (expression (',' expression)*)? expression : assignment assignment : conditional
| unary '=' expression
conditional : logical_or | logical_or '?' expression ':' conditional logical_or : logical_and | logical_or '||' logical_and logical_and : equality | logical_and '&&' equality equality : relational | equality ('=='|'!=') relational relational : additive | relational ('<'|'>'|'<='|'>=') additive additive : multiplicative | additive ('+'|'-') multiplicative multiplicative : unary | multiplicative ('*'|'/'|'%') unary unary : postfix
| ('-'|'~'|'!'|'&'|'*') unary | '(' type ')' unary
postfix : primary | Identifier '(' expression_list ')' primary : Integer | '(' expression ')' | Identifier

step11 语义规范

11.1. 左值表达式除了能通过 5.5 中两条规则得到,新增一条规则:

  • 如果 e 是类型为 T* 的表达式,那么 *e 是类型为 T 的左值。

    因此 int a; *&a=2;*&a 是左值。

11.2. step11 中类型只有 int 和指针类型。禁止隐式类型转换,但允许显式类型转换,只要不违反其他几条规范。

11.3. & 的操作数必须是左值。

所以 &*e 等价于 e,但它不是左值了

11.4. * 的操作数类型必须是指针类型。

11.5. 指针类型的表达式仅能参与如下运算:类型转换、(一元)&*、(二元)==!=。 指针不得参与乘除模和、一元、比较大小、逻辑运算。step12 会支持算术。

11.6. 空指针是值为 0 的指针。 因为禁止隐式类型转换,所以空指针字面量必须由 0 显示转换而来,例如 (int*) 0。 判断空指针类似:if (p == (int**)0) ;if ((int)p = 0) ;

11.7. 未对齐的指针是未定义行为。就 step11 而言,指针必须对齐到 4 字节边界。

11.8. 只要指针类型和被指向的对象的类型不匹配,空指针除外,就是未定义行为,哪怕没有解引用。

所以 int a; int *p = (int*)a; 包含了未定义行为。

results matching ""

    No results matching ""

    results matching ""

      No results matching ""