zaach / jison

Bison in JavaScript.
http://jison.org
4.34k stars 448 forks source link

Error `got 'EOF'` #330

Closed daiyam closed 7 years ago

daiyam commented 7 years ago

Hello,

I'm stuck on a should be simple parser. Without any conflicts.

I'm getting the error Expecting ')', ',', 'NEWLINE', got 'EOF'. It's as if the parser consumes all the data but revert to an invalid status.

Here my Jison file:

%lex
%%

[^\n\S]+        /* skip whitespace */
'extern'        return 'EXTERN'
'->'            return '->'
'('             return '('
')'             return ')'
'{'             return '{'
'}'             return '}'
':'             return ':'
','             return ','
'...'           return '...'
\n              return 'NEWLINE'
[-_$A-Za-z]\w*  return 'IDENTIFIER'
<<EOF>>         return 'EOF'
.               return 'INVALID'

/lex

%start ExternDeclaration

%%

FunctionParameter
: '...' Identifier ':' TypeVar
| '...' Identifier
| Identifier ':' TypeVar
| Identifier
;

FunctionParameterList
: '(' FunctionParameterListList ')'
| '(' ')'
;

FunctionParameterListList
: FunctionParameterListList ',' FunctionParameter
| FunctionParameter
;

FunctionReturn
: '->' TypeVar
;

Identifier
: 'IDENTIFIER'
;

TypeVar
: TypeObject
{
    console.log('done')
}
| Identifier
{
    console.log($1)
}
;

TypeObject
: '{' TypePropertyList '}'
| '{' TypeProperty '}'
| '{' '}'
;

TypeProperty
: Identifier FunctionParameterList FunctionReturn
{
    console.log('TypeProperty:', $1)
}
;

TypePropertyList
: TypePropertyList TypeProperty 'NEWLINE'
| TypeProperty 'NEWLINE'
;

ExternDeclaration
: 'EXTERN' Identifier ':' TypeVar
;
%%

and my test file:

extern console: {
    log(...args) -> void
    time(label: string) -> void
    timeEnd(label: string) -> void
}

Thx Daiyam

daiyam commented 7 years ago

I really don't know what I'm doing wrong... :tired_face:

I'm doing a parser for template strings but I'm getting the same kind of error...

Parse error on line 1:
`hello $(name)`
---------------^
Expecting ',', ')', got 'EOF'

with the text:

`hello $(name)`

and the syntax

%lex
%x template
%%

\s+              /* skip whitespace */
<template>'`'    this.popState();return 'END'
<template>'$('   this.begin('');return '$('
<template>.      return 'TEMPLATE_VALUE'
'`'              this.begin('template');return 'BEGIN'
'('              this.begin('');return '('
')'              this.popState();return ')'
','              return ','
[-_$A-Za-z]\w*   return 'IDENTIFIER'
<<EOF>>          return 'EOF'
.                return 'INVALID'

/lex

%start Expression

%%

Arguments
: Arguments ',' Expression
| Expression
;

Expression
: Identifier '(' Arguments ')'
| Identifier
| Template
;

Identifier
: 'IDENTIFIER'
;

Template
: 'BEGIN' TemplateValues 'END'
;

TemplateValues
: TemplateValues 'TEMPLATE_VALUE'
| TemplateValues '$(' Expression ')'
| 'TEMPLATE_VALUE'
;

%%
yosbelms commented 7 years ago

@daiyam

Your lexer recognizes 'EOF' but you never use it in parser productions, you must take into account that every source has 'EOF', so, try to change the start condition to some rule that regards 'EOF', example:

...
%start Program

%%

Program
    : Expression EOF

...

please, let me know if this solves your problem.

daiyam commented 7 years ago

@yosbelms Thanks you.

Just need to remove the <<EOF>> return 'EOF' and everything is fine.

Sometimes it's so much in your face that you don't see it...