I have rules. I will give a stripped-down code.

translation_unit :declaration_seq_opt; declaration_seq_opt: |declaration_seq; declaration_seq :declaration |declaration_seq declaration; declaration :block_declaration |linkage_specification ; block_declaration :simple_declaration ; simple_declaration :decl_specifier_seq identifier ';' ; decl_specifier_seq_opt : |decl_specifier_seq ; decl_specifier_seq :decl_specifier_seq_opt decl_specifier ; decl_specifier :storage_class_specifier |type_specifier ; storage_class_specifier :EXTERN ; type_specifier :simple_type_specifier ; simple_type_specifier :INT ; identifier :ID ; string_literal :STRING ; linkage_specification: EXTERN string_literal '{' declaration_seq_opt '}' | EXTERN string_literal declaration ; 

on the text extern int a1; throws an error syntax error, unexpected INT, expecting STRING .

As I understand it, the parser wants STRING. went according to the linkage_specification rule , but there is the same block_declaration rule in which this line should be dealt with but it persists in linkage_specification and I don’t understand why.

Analyzed dump bison.

Log of work:

 Starting parse Entering state 0 Reading a token: Next token is token EXTERN () Shifting token EXTERN () Entering state 3 Reading a token: Next token is token INT () Error: popping token EXTERN () Stack now 0 Cleanup: discarding lookahead token INT () 

Call dump:

 State 0 0 $accept: . translation_unit $end 1 translation_unit: . declaration_seq_opt 2 declaration_seq_opt: . %empty [$end] 3 | . declaration_seq 4 declaration_seq: . declaration 5 | . declaration_seq declaration 6 declaration: . block_declaration 7 | . linkage_specification 8 block_declaration: . simple_declaration 9 simple_declaration: . decl_specifier_seq identifier ';' 10 decl_specifier_seq_opt: . %empty [EXTERN, INT] 11 | . decl_specifier_seq 12 decl_specifier_seq: . decl_specifier_seq_opt decl_specifier 20 linkage_specification: . EXTERN string_literal '{' declaration_seq_opt '}' 21 | . EXTERN string_literal declaration EXTERN сдвиг, и переход в состояние 1 EXTERN [вывод с использованием правила 10 (decl_specifier_seq_opt)] INT вывод с использованием правила 10 (decl_specifier_seq_opt) $default вывод с использованием правила 2 (declaration_seq_opt) translation_unit переход в состояние 2 declaration_seq_opt переход в состояние 3 declaration_seq переход в состояние 4 declaration переход в состояние 5 block_declaration переход в состояние 6 simple_declaration переход в состояние 7 decl_specifier_seq_opt переход в состояние 8 decl_specifier_seq переход в состояние 9 linkage_specification переход в состояние 10 State 1 19 string_literal: . STRING 20 linkage_specification: EXTERN . string_literal '{' declaration_seq_opt '}' 21 | EXTERN . string_literal declaration STRING сдвиг, и переход в состояние 11 string_literal переход в состояние 12 State 2 0 $accept: translation_unit . $end $end сдвиг, и переход в состояние 13 State 3 1 translation_unit: declaration_seq_opt . $default вывод с использованием правила 1 (translation_unit) 

Enabled glr with %glr-parser . According to the dock, that's all you need. But I have %skeleton "lalr1.cc" , and in the question below they talk about %skeleton "glr.cc" but with this skilllet I do not compile with errors:

 ParserC.cpp:1149:13: error: object of type 'yyGLRStackItem' cannot be assigned because its copy assignment operator is implicitly deleted *yyp1 = *yyp0; ^ ParserC.cpp:722:14: note: copy assignment operator of 'yyGLRStackItem' is implicitly deleted because field 'yystate' has a deleted copy assignment operator yyGLRState yystate; ^ ParserC.cpp:691:5: note: copy assignment operator of 'yyGLRState' is implicitly deleted because field 'yysemantics' has a deleted copy assignment operator } yysemantics; ^ ParserC.cpp:690:13: note: copy assignment operator of '' is implicitly deleted because variant field 'yysval' has a non-trivial copy assignment operator YYSTYPE yysval; ^ ParserC.cpp:1371:22: error: call to implicitly-deleted default constructor of 'yyGLRStackItem [6]' yyGLRStackItem yyrhsVals[YYMAXRHS + YYMAXLEFT + 1]; ^ ParserC.cpp:722:14: note: default constructor of 'yyGLRStackItem' is implicitly deleted because field 'yystate' has a deleted default constructor yyGLRState yystate; ^ ParserC.cpp:691:5: note: default constructor of 'yyGLRState' is implicitly deleted because field 'yysemantics' has a deleted default constructor } yysemantics; ^ ParserC.cpp:690:13: note: default constructor of '' is implicitly deleted because variant field 'yysval' has a non-trivial default constructor YYSTYPE yysval; ^ ParserC.cpp:1640:18: error: call to implicitly-deleted default constructor of 'yyGLRStackItem [6]' yyGLRStackItem yyrhsVals[YYMAXRHS + YYMAXLEFT + 1]; ^ ParserC.cpp:722:14: note: default constructor of 'yyGLRStackItem' is implicitly deleted because field 'yystate' has a deleted default constructor yyGLRState yystate; ^ ParserC.cpp:691:5: note: default constructor of 'yyGLRState' is implicitly deleted because field 'yysemantics' has a deleted default constructor } yysemantics; ^ ParserC.cpp:690:13: note: default constructor of '' is implicitly deleted because variant field 'yysval' has a non-trivial default constructor YYSTYPE yysval; ^ ParserC.cpp:1675:14: error: call to implicitly-deleted default constructor of 'yyGLRState' yyGLRState yyleftmost_state; ^ ParserC.cpp:691:5: note: default constructor of 'yyGLRState' is implicitly deleted because field 'yysemantics' has a deleted default constructor } yysemantics; ^ ParserC.cpp:690:13: note: default constructor of '' is implicitly deleted because variant field 'yysval' has a non-trivial default constructor YYSTYPE yysval; ^ ParserC.cpp:1862:37: error: object of type 'yyGLRState' cannot be assigned because its copy assignment operator is implicitly deleted yystackp->yynextFree->yystate = *yyr; ^ ParserC.cpp:691:5: note: copy assignment operator of 'yyGLRState' is implicitly deleted because field 'yysemantics' has a deleted copy assignment operator } yysemantics; ^ ParserC.cpp:690:13: note: copy assignment operator of '' is implicitly deleted because variant field 'yysval' has a non-trivial copy assignment operator YYSTYPE yysval; 

If glr really does not work then this error is logical. the parser tries to resolve the shift / convolution conflict in favor of the shift and ignores the decl_specifier_seq_opt that needs the convolution.

I found another question on a similar problem, but there is no answer to it. The feeling that glr does not work at all.

  • And if the rule linkage_specification for a while completely removed from the declaration ? - VladD
  • @VladD then parse well. Now I will correct the issue with new data. - Ilya Chizhanov
  • Okay, so you have a reduce / reduce-conflict, and you want to get around it with glr? Understand. - VladD
  • @VladD shift / reduce to be exact. Yes. At first, I simply did not want to correct the grammar, but now to find the problem is rather a matter of principle. - Ilya Chizhanov
  • The name lalr1.cc hints that it should not work out with it. - VladD

1 answer 1

This rule is chosen because the parser is not glr , but LALR (1) because This is specified in the skeleton directive.

Because this is LALR (1) then the error is expected because the conflict would be resolved in the direction of linkage_specification . It corresponds to shift in shift / reduce with decl_specifier_seq_opt (which can be empty and corresponds to reduce).

In order for the parser to become glr, you must specify %skeleton "glr.cc" , and errors arise because the type is not simple.

In the dock (see 1.5.3.3), a restriction is imposed on the type of semantic meaning. It must be POD.

  • Is it possible then to use a pointer? - VladD
  • @VladD is possible. pointers the same POD. but in this case, you need a very meticulous attitude to memory leaks. - Ilya Chizhanov
  • Yeah, I'm talking about the same thing, it’s a pity that a smart pointer shouldn’t be - VladD