praeclarum / CLanguage

C parser, compiler, and interpreter for .NET
MIT License
269 stars 32 forks source link

Reduce/reduce conflict parsing constructor definitions #43

Open mingodad opened 10 months ago

mingodad commented 10 months ago

I've just added this project grammar to https://mingodad.github.io/parsertl-playground/playground/ an Yacc/Lex compatible online editor/tester (select CLanguage parser from Examples then click Parse to see the parser tree for the content in Input source).

Any feedback is welcome !

This grammar has one reduce/reduce conflict that will prevent the execution of ctor_identifier_list production:

State 1

  114 type_specifier: TYPE_NAME •
  256 ctor_identifier_list: TYPE_NAME •

    COLONCOLON  reduce using rule 256 (ctor_identifier_list)
    '('         reduce using rule 114 (type_specifier)
    '('         [reduce using rule 256 (ctor_identifier_list)]
    $default    reduce using rule 114 (type_specifier)

    reduce/reduce conflict on token '(':
      114 type_specifier: TYPE_NAME •
      256 ctor_identifier_list: TYPE_NAME •
      First example: TYPE_NAME • '(' declarator ')' declaration_list compound_statement $end
      First reduce derivation
        $accept
        ↳ 0: translation_unit                                                                                                   $end
             ↳ 248: external_declaration
                    ↳ 250: function_definition
                           ↳ 254: declaration_specifiers   declarator                       declaration_list compound_statement
                                  ↳ 85: type_specifier     ↳ 138: direct_declarator
                                        ↳ 114: TYPE_NAME •        ↳ 144: '(' declarator ')'
      Second example: TYPE_NAME • '(' ')' compound_statement $end
      Second reduce derivation
        $accept
        ↳ 0: translation_unit                                                     $end
             ↳ 248: external_declaration
                    ↳ 253: ctor_definition
                           ↳ 259: ctor_identifier_list '(' ')' compound_statement
                                  ↳ 256: TYPE_NAME •
praeclarum commented 7 months ago

Very very cool!!! Thank you. This looks like a lot of work and it's much appreciated.

I was able to use your tool to play around and find a fix that reduce/reduce. Just need to update my code...

Feedback

For feedback, I would say better parse error messages would be appreciated. Right now the bottom right window goes blank. Would be nice to know how far it made it, a stack of productions, and maybe expected tokens.

I would also appreciate that full conflict report you put in this issue onto the app itself. I stick at fixing conflicts and need all the help I can get!

I'm sure it's asking a BIT too much, but it would be fun if you could translate the conflict examples into real examples by substituting some synthetic data for the tokens. I realize I'm being lazy here, but it would be a super cool party trick to get real example texts when there is an error.

My Fix

For my own notes, I should remove ctor_identifier_list all together and simply allow function definitions without types:

translation_unit :
    external_declaration
    | translation_unit external_declaration
    ;

external_declaration :
    function_definition
    | declaration
    | ';'
    ;

function_definition :
    declaration_specifiers declarator declaration_list compound_statement
    | declaration_specifiers declarator compound_statement
    | declarator compound_statement
    ;

declaration_list :
    declaration
    | preproc declaration
    | declaration_list declaration
    ;