Legend Since 1984
Cruising between Fantasy and Reality...

Tuesday, June 13, 2006

Understanding the C Grammar

作完C的语法分析,一边感叹C语言文法的复杂,一边再次试图理解其文法构成。查阅MSDN的时候发现完整的C++语言有18级运算符优先级,而我自己写的文法只有4级。C语言怎么说也有15级优先级,那么这样的优先级在文法中是怎么实现的呢? 总算从

  • primary_expression->IDENTIFIER
  • primary_expression->CONSTANT
  • primary_expression->STRING_LITERAL
  • primary_expression->( expression )
看出了一点蛛丝马迹。类比我自定义的文法,primary_expression应该是处于最底层的与表达式相关非终结符了。再自底向上顺藤摸瓜,发现了
  • expression(,)-->
  • assignment_expression(= += -= *= /= etc)-->
  • conditional_expression(?:)-->
  • logical_or_expression(||)-->
  • logical_and_expression(&&)-->
  • inclusive_or_expression()->
  • exclusive_or_expression(^)-->
  • and_expression(&)-->
  • equality_expression(== !=)-->
  • relational_expression(< > <= >=)-->
  • shift_expression(<< >>)-->
  • additive_expression(+ -)-->
  • multiplicative_expression(* / %)-->
  • cast_expression( (type name) )-->
  • unary_expression(++ -- & * + - ~ ! sizeof)-->
  • postfix_expression(++ -- . -> () (argument_list) [])-->
  • primary_expression( () )

的层次体系。从各个非终结符的名字就可以很容易看出他们代表的运算符(如后面的括号所示)。从上到下运算符的优先级越来越高。一共是17个优先级。比C++少了'::'和'throw'的运算符所在的优先级。

理解了算符表达式(expression)的结构,C文法已经完成了1/3的数量。有了这个突破口,在理解其他的文法就只是时间问题了。

ps: 原文法中产生式unary_expression->unary_operator cast_expression显然是不合理的,因为cast_expression是unary_expression的上一级,这样将导致求Follow集的循环递归调用。改为unary_expression->unary_operator unary_expression解决了问题而不会改变语言的定义。

Labels:

0 Comments:

Post a Comment

<< Home