GerHobbelt / jison

bison / YACC / LEX in JavaScript (LALR(1), SLR(1), etc. lexer/parser generator)
https://gerhobbelt.github.io/jison/
MIT License
117 stars 20 forks source link

Can't parse postgresql grammar and missing error location #68

Open mingodad opened 2 years ago

mingodad commented 2 years ago

I'm testing jison with a naked postgresql-13.3 grammar generated by a modifed bison (see https://github.com/mingodad/lalr-parser-test) the naked grammar is parsed properly by bison and byacc see attached grammar gram.y.naked.zip

The output:

$./node dist/cli-cjs-es5.js gram.y.naked
dist/cli-cjs-es5.js:19824
                throw err;
                ^

JisonParserError: 
You cannot specify a precedence override for an epsilon (a.k.a. empty) rule!

  Erroneous area:

    at Object.parseError (dist/cli-cjs-es5.js:14994:19)
    at Object.yyError (dist/cli-cjs-es5.js:15133:29)
    at Object.parser__PerformAction (dist/cli-cjs-es5.js:14637:34)
    at Object.parse (dist/cli-cjs-es5.js:16127:48)
    at Object.parse (dist/cli-cjs-es5.js:18717:23)
    at autodetectAndConvertToJSONformat (dist/cli-cjs-es5.js:19799:36)
    at new Jison_Generator (dist/cli-cjs-es5.js:25327:15)
    at Object.generateParserString (dist/cli-cjs-es5.js:25836:25)
    at processInputFile (dist/cli-cjs-es5.js:25751:30)
    at Object.cliMain [as main] (dist/cli-cjs-es5.js:25829:13)
mingodad commented 2 years ago

Going through the stack trace and adding this line here (dist/cli-cjs-es5.js:14994:19) :

        if (!chk_g) {
            try {
                chk_g = ebnfParser.parse(grammar, options);
            } catch (e) {
                ...
                console.log(ebnfParser.bnf_parser.parser.__error_infos); ////!!!! inside here it's the  line: 4465
                throw err;
            }
        }

But probably there is a better way to show the offending line number.

mingodad commented 2 years ago

Here is the original rule:

opt_existing_window_name:
    ColId   { $opt_existing_window_name = $ColId; }
    | /*EMPTY*/             %prec Op    { $opt_existing_window_name = NULL; }
        ;

And here the naked rule:

opt_existing_window_name :
    ColId
    | %prec Op /*14L*/ /*empty*/
    ;

Somehow byacc/bison manage to associate precedence to empty rules.