Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error in online playground #206

Closed
mingodad opened this issue Jun 1, 2022 · 4 comments
Closed

Error in online playground #206

mingodad opened this issue Jun 1, 2022 · 4 comments

Comments

@mingodad
Copy link
Contributor

mingodad commented Jun 1, 2022

This grammar nuke the online playground:
Console error message:

Uncaught (in promise) 5405224

Experimental Lua grammar:

chunk <-
	 SHEBANG? SKIP Block ! . #~{ synerr(yy, "unexpected syntax"); }

SHEBANG <-
	 '#!' ( ! LINEBREAK . )* LINEBREAK?

SKIP <-
	 ( SPACE+ / COMMENT )*

Block <-
	 ( Label / Return / Break / Goto / Do / While / Repeat / If / ForNum / ForIn / FuncDef / FuncDecl / VarDecl / Assign / call / ( ';' SKIP ) )*

Label <-
	 '::' NAME '::' SKIP

Return <-
	 'return' SKIP exprlist?

Break <-
	 'break' SKIP

Goto <-
	 'goto' SKIP NAME

Do <-
	 'do' SKIP Block 'end' SKIP

While <-
	 'while' SKIP expr 'do' SKIP Block 'end' SKIP

Repeat <-
	 'repeat' SKIP Block 'until' SKIP expr

If <-
	 'if' SKIP expr 'then' SKIP Block ( 'elseif' SKIP expr 'then' SKIP Block )* ( 'else' SKIP Block )? 'end' SKIP

ForNum <-
	 'for' SKIP Id '=' SKIP expr ',' SKIP expr ( ',' SKIP expr )? 'do' SKIP Block 'end' SKIP

ForIn <-
	 'for' SKIP idlist 'in' SKIP exprlist 'do' SKIP Block 'end' SKIP

FuncDef <-
	 'function' SKIP funcname funcbody

FuncDecl <-
	 'local' SKIP 'function' SKIP Id funcbody

VarDecl <-
	 'local' SKIP iddecllist ( '=' SKIP exprlist )?

Assign <-
	 varlist '=' SKIP exprlist

call <-
	 exprprimary ( ( indexsuffix+ callsuffix ) / callsuffix )+

NAME <-
	 ! KEYWORD ( NAME_PREFIX NAME_SUFFIX? ) SKIP

exprlist <-
	 expr ( ',' SKIP expr )*

expr <-
	 expror

Id <-
	 NAME

idlist <-
	 Id ( ',' SKIP Id )*

funcname <-
	 Id DotIndex* ColonIndex?

funcbody <-
	 '(' SKIP funcargs ')' SKIP Block 'end' SKIP

iddecllist <-
	 IdDecl ( ',' SKIP IdDecl )*

varlist <-
	 var ( ',' SKIP var )*

Number <-
	 NUMBER SKIP

NUMBER <-
	 HEX_NUMBER
	/ DEC_NUMBER

String <-
	 STRING SKIP

STRING <-
	 STRING_SHRT
	/ STRING_LONG

Boolean <-
	 ( 'false' SKIP )
	/ ( 'true' SKIP )

Nil <-
	 'nil' SKIP

Varargs <-
	 '...' SKIP

IdDecl <-
	 NAME ( '<' SKIP NAME '>' SKIP )?

Function <-
	 'function' SKIP funcbody

Table <-
	 '{' SKIP ( field ( fieldsep field )* fieldsep? )? '}' SKIP

field <-
	 Pair
	/ expr

fieldsep <-
	 ( ',' SKIP )
	/ ( ';' SKIP )

Paren <-
	 '(' SKIP expr ')' SKIP

Pair <-
	 ( '[' SKIP expr ']' SKIP '=' SKIP expr )
	/ ( NAME '=' SKIP expr )

Call <-
	 callargs

callargs <-
	 ( '(' SKIP ( expr ( ',' SKIP expr )* )? ')' SKIP )
	/ Table
	/ String

CallMethod <-
	 ':' SKIP NAME callargs

DotIndex <-
	 '.' SKIP NAME

ColonIndex <-
	 ':' SKIP NAME

KeyIndex <-
	 '[' SKIP expr ']' SKIP

indexsuffix <-
	 DotIndex
	/ KeyIndex

callsuffix <-
	 Call
	/ CallMethod

var <-
	 ( exprprimary ( ( callsuffix+ indexsuffix ) / indexsuffix )+ )
	/ Id

exprprimary <-
	 Id
	/ Paren

exprsuffixed <-
	 exprprimary ( indexsuffix / callsuffix )*

funcargs <-
	 ( ( Id ( ',' SKIP Id )* ( ',' SKIP Varargs )? ) / Varargs )?

opor <-
	 'or' SKIP exprand

exprand <-
	 exprcmp opand*

opand <-
	 'and' SKIP exprcmp

exprcmp <-
	 exprbor opcmp*

opcmp <-
	 ( ( '==' SKIP ) / ( '~=' SKIP ) / ( '<=' SKIP ) / ( '>=' SKIP ) / ( '<' SKIP ) / ( '>' SKIP ) ) exprbor

exprbor <-
	 exprbxor opbor*

opbor <-
	 '|' SKIP exprbxor

exprbxor <-
	 exprband opbxor*

opbxor <-
	 '~' SKIP exprband

exprband <-
	 exprbshift opband*

opband <-
	 '&' SKIP exprbshift

exprbshift <-
	 exprconcat opbshift*

opbshift <-
	 ( ( '<<' SKIP ) / ( '>>' SKIP ) ) exprconcat

exprconcat <-
	 exprarit opconcat*

opconcat <-
	 '..' SKIP exprconcat

oparit <-
	 ( ( '+' SKIP ) / ( '-' SKIP ) ) exprfact

exprfact <-
	 exprunary opfact*

opfact <-
	 ( ( '*' SKIP ) / ( '//' SKIP ) / ( '/' SKIP ) / ( '%' SKIP ) ) exprunary

exprunary <-
	 opunary
	/ exprpow

oppow <-
	 '^' SKIP exprunary

opunary <-
	 ( ( 'not' SKIP ) / ( '#' SKIP ) / ( '-' SKIP ) / ( '~' SKIP ) ) exprunary

expror <-
	 exprand opor*

exprarit <-
	 exprfact oparit*

exprpow <-
	 exprsimple oppow*

exprsimple <-
	 Nil
	/ Boolean
	/ Number
	/ String
	/ Varargs
	/ Function
	/ Table
	/ exprsuffixed

STRING_SHRT <-
	 $quote(["']) ( ESCAPE_SEQ / ( ! ( $quote / LINEBREAK ) . ) )* $quote

STRING_LONG <-
	 '[' $lsep('='*) '[' LINEBREAK? ( ! (']' $lsep ']') . )* ']' $lsep ']'

ESCAPE_SEQ <-
	 '\\' ESCAPE

LINEBREAK <-
	 '\r\n'
	/ '\n\r'
	/ '\n'
	/ '\r'

ESCAPE <-
	 [\'"]
	/ ( 'n' / 't' / 'r' / 'a' / 'b' / 'v' / 'f' )
	/ ( 'x' HEX_DIGIT HEX_DIGIT )
	/ ( 'u' '{' HEX_DIGIT HEX_DIGIT+ '}' )
	/ ( 'z' SPACE* )
	/ (DEC_DIGIT DEC_DIGIT !DEC_DIGIT / [012] DEC_DIGIT DEC_DIGIT)
	/ LINEBREAK

HEX_DIGIT <-
	 [0-9a-fA-F]

SPACE <-
	 ' '
	/ '\t'
	/ LINEBREAK

HEX_NUMBER <-
	 '0' [xX] HEX_PREFIX ( [pP] EXP_DIGITS )?

DEC_NUMBER <-
	 DEC_PREFIX ( [eE] EXP_DIGITS )?

HEX_PREFIX <-
	 ( HEX_DIGIT+ ( '.' HEX_DIGIT* )? )
	/ ( '.' HEX_DIGIT+ )

EXP_DIGITS <-
	 [+-]? DEC_DIGIT+

DEC_PREFIX <-
	 ( DEC_DIGIT+ ( '.' DEC_DIGIT* )? )
	/ ( '.' DEC_DIGIT+ )

DEC_DIGIT <-
	 [0-9]

COMMENT <-
	 '--' ( STRING_LONG / COMMENT_SHRT )

COMMENT_SHRT <-
	 ( ! LINEBREAK . )*

KEYWORD <-
	 ('and'
	/ 'break'
	/ 'do'
	/ 'elseif'
	/ 'else'
	/ 'end'
	/ 'false'
	/ 'for'
	/ 'function'
	/ 'goto'
	/ 'if'
	/ 'in'
	/ 'local'
	/ 'nil'
	/ 'not'
	/ 'or'
	/ 'repeat'
	/ 'return'
	/ 'then'
	/ 'true'
	/ 'until'
	/ 'while') !NAME_PREFIX

NAME_PREFIX <-
	 [_a-zA-Z]

NAME_SUFFIX <-
	 [_a-zA-Z0-9]+

EXTRA_TOKENS <-
	 '[[' '[=' '--'
@yhirose
Copy link
Owner

yhirose commented Jun 1, 2022

@mingodad, could you make it smaller which can still reproduce the problem? Thanks.

@mingodad
Copy link
Contributor Author

mingodad commented Jun 2, 2022

sample.lua:

local lpeg = require 'lpeglabel'

On the command line:

./peglint lua.peglib sample.lua 
lua.peglib:346:1: 'EXTRA_TOKENS' is not referenced.
terminate called after throwing an instance of 'std::runtime_error'
  what():  Invalid back reference...
Aborted (core dumped)

With gdb:

gdb --args ./peglint lua.peglib sample.lua 
GNU gdb (Ubuntu 10.2-0ubuntu1~18.04~2) 10.2
...
(gdb) r
Starting program: /home/mingo/dev/c/A_grammars/cpp-peglib0/build/lint/peglint lua.peglib sample.lua
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
lua.peglib:346:1: 'EXTRA_TOKENS' is not referenced.
terminate called after throwing an instance of 'std::runtime_error'
  what():  Invalid back reference...

Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51	../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007ffff71de7f1 in __GI_abort () at abort.c:79
#2  0x00007ffff7a630a9 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3  0x00007ffff7a6e506 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4  0x00007ffff7a6e571 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5  0x00007ffff7a6e7f5 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x0000555555570243 in peg::BackReference::parse_core (this=0x555555888020, 
    s=0x555555865f3d "require 'lpeglabel'.", n=19, vs=..., c=..., dt=std::any [no contained value])
    at /home/mingo/dev/c/A_grammars/cpp-peglib0/lint/../peglib.h:2814
#7  0x000055555556edf4 in peg::Ope::parse (this=0x555555888020, s=0x555555865f3d "require 'lpeglabel'.", n=19, 
    vs=..., c=..., dt=std::any [no contained value]) at /home/mingo/dev/c/A_grammars/cpp-peglib0/lint/../peglib.h:2626
#8  0x000055555556536a in peg::Sequence::parse_core (this=0x5555558886e0, s=0x555555865f3d "require 'lpeglabel'.", 
    n=19, vs=..., c=..., dt=std::any [no contained value])
    at /home/mingo/dev/c/A_grammars/cpp-peglib0/lint/../peglib.h:1000
#9  0x000055555556edf4 in peg::Ope::parse (this=0x5555558886e0, s=0x555555865f3d "require 'lpeglabel'.", n=19, 
    vs=..., c=..., dt=std::any [no contained value]) at /home/mingo/dev/c/A_grammars/cpp-peglib0/lint/../peglib.h:2626
#10 0x000055555556f33f in peg::Holder::parse_core(char const*, unsigned long, peg::SemanticValues&, peg::Context&, std::any&) const::{lambda(std::any&)#1}::operator()(std::any&) const (__closure=0x7fffffff63f0, 
    a_val=std::any [no contained value]) at /home/mingo/dev/c/A_grammars/cpp-peglib0/lint/../peglib.h:2702
#11 0x000055555558f2b1 in peg::Context::packrat<peg::Holder::parse_core(char const*, unsigned long, peg::SemanticValues&, peg::Context&, std::any&) const::{lambda(std::any&)#1}>(char const*, unsigned long, unsigned long&, std::any&, peg::Holder::parse_core(char const*, unsigned long, peg::SemanticValues&, peg::Context&, std::any&) const::{lambda(std::any&)#1}) (this=0x7fffffffd170, a_s=0x555555865f3d "require 'lpeglabel'.", def_id=44, 
    len=@0x7fffffff6460: 93824995592520, val=std::any [no contained value], fn=...)
    at /home/mingo/dev/c/A_grammars/cpp-peglib0/lint/../peglib.h:871
#12 0x000055555556f821 in peg::Holder::parse_core (this=0x555555888950, s=0x555555865f3d "require 'lpeglabel'.", 
    n=19, vs=..., c=..., dt=std::any [no contained value])
    at /home/mingo/dev/c/A_grammars/cpp-peglib0/lint/../peglib.h:2691
#13 0x000055555556edf4 in peg::Ope::parse (this=0x555555888950, s=0x555555865f3d "require 'lpeglabel'.", n=19, 
    vs=..., c=..., dt=std::any [no contained value]) at /home/mingo/dev/c/A_grammars/cpp-peglib0/lint/../peglib.h:2626

@mingodad
Copy link
Contributor Author

mingodad commented Jun 2, 2022

And here is the minimal grammar that shows the problem:

STRING_SHRT <-
	 $quote(["']) ( !$quote . )* $quote

@yhirose yhirose closed this as completed in bd99157 Jun 2, 2022
@yhirose
Copy link
Owner

yhirose commented Jun 2, 2022

@mingodad, thanks! I fixed the crash. cpp-peglib now reports undefined back reference errors.

> peglint lua.peg sample.lua
lua.peg:259:3: The back reference 'quote' is undefined.
lua.peg:259:37: The back reference 'quote' is undefined.
lua.peg:259:65: The back reference 'quote' is undefined.
lua.peg:262:7: The back reference 'lsep' is undefined.
lua.peg:262:43: The back reference 'lsep' is undefined.
lua.peg:262:63: The back reference 'lsep' is undefined.

Here is the correct grammar:

STRING_SHRT <-
	 $quote<["']> ( ESCAPE_SEQ / ( ! ( $quote / LINEBREAK ) . ) )* $quote

STRING_LONG <-
	 '[' $lsep<'='*> '[' LINEBREAK? ( ! (']' $lsep ']') . )* ']' $lsep ']'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants