Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
604 views
in Technique[技术] by (71.8m points)

c - C11 grammar ambiguity between _Atomic type specifier and qualifier

I'm trying to write a lex/yacc grammar for C11 based off of N1570. Most of my grammar is copied verbatim from the informative syntax summary, but some yacc conflicts arose. I've managed to resolve all of them except for one: there seems to be some ambiguity between when '_Atomic' is used as a type specifier and when it's used as a type qualifier.

In the specifier form, _Atomic is followed immediately by parentheses, so I'm assuming it has something to do with C's little-used syntax which allows declarators to be in parentheses, thus allowing parentheses to immediately follow a qualifier. But my grammar already knows how to differentiate typedef names from other identifiers, so yacc should know the difference, shouldn't it?

I can't for the life of me think of a case when it would actually be ambiguous.

I doubt it helps, but here's the relevant state output I get when I use yacc's -v flag. "ATOMIC" is obviously my token name for "_Atomic"

state 23

  152 atomic_type_specifier: ATOMIC . '(' type_name ')'
  156 type_qualifier: ATOMIC .

    '('  shift, and go to state 49

    '('       [reduce using rule 156 (type_qualifier)]
    $default  reduce using rule 156 (type_qualifier)
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Okay, whether or not we can come up with a grammatically ambiguous case doesn't matter. Section 6.7.2.4 paragraph 4 of N1570 states that:

If the _Atomic keyword is immediately followed by a left parenthesis, it is interpreted as a type specifier (with a type name), not as a type qualifier.

To enforce this, I simply made _Atomic as a specifier and _Atomic as a qualifier separate tokens in my lex rules.

"_Atomic"/{WHITESPACE}*"(" {return ATOMIC_SPECIFIER;}
"_Atomic"                  {return ATOMIC_QUALIFIER;}

I'm relatively new to lex/yacc and parser generators in general, but my gut says this is kind of a hack. At the same time, what else would the trailing context syntax in lex be for?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...