An open API service indexing awesome lists of open source software.

https://github.com/lezgomatt/lpeglabel-gsoc-2016

Summary of my GSoC 2016 project and experience
https://github.com/lezgomatt/lpeglabel-gsoc-2016

Last synced: 5 months ago
JSON representation

Summary of my GSoC 2016 project and experience

Awesome Lists containing this project

README

          

This page talks about my
[Google Summer of Code (GSoC) project](https://summerofcode.withgoogle.com/projects/#5054385788813312)
and experience during the summer of 2016. I was fortunate enough
to be accepted by [LabLua](http://www.lua.inf.puc-rio.br/index.html),
and help them test out the idea of using labeled failures to improve
error messages in PEG-based parsers.

You can also read LabLua's GSoC 2016 wrap-up
[here](http://www.lua.inf.puc-rio.br/gsoc/blog2016.html)
or on
[Google's Open Source Blog](https://opensource.googleblog.com/2017/02/google-summer-of-code-2016-wrap-up_8.html).

# Introduction

[Parsing Expression Grammars (PEGs)](https://en.wikipedia.org/wiki/Parsing_expression_grammar)
are an expressive formalism for designing and implementing
top-down parsers with local backtracking. PEGs are an alternative to
[Context Free Grammars (CFGs)](https://en.wikipedia.org/wiki/Context-free_grammar),
which have a similar (but different) level of expressiveness.

An issue that users of PEG-based parsers face is poor reporting of
syntax errors on the part of PEG-based parsers.
[Labeled failures](http://arxiv.org/abs/1405.6646)
are an extension to PEGs that aims to
address this issue by annotating a PEG with labels corresponding to
syntax errors, improving the quality of error messages generated by
a PEG-based parser.

[LPegLabel](https://github.com/sqmedeiros/lpeglabel) is an extension of
the [LPeg](http://www.inf.puc-rio.br/~roberto/lpeg/) that provides
an implementation of PEGs with labeled failures. Labels can be used to
signal different kinds of errors and to specify which alternative in
a labeled ordered choice should handle a given label, which is useful for
implementing error recovery.

# Goal

The goal of this project was to rewrite the (LPeg) parsers of some
Lua libraries, such as the module re from LPeg (actually it was
LPegLabel's version of the module called relabel that was modified)
and lua-parser, by using LPegLabel. By rewriting them, we are able to
get parsers with better error messages.

In the end, three parsers were rewritten for this project:
* [relabel](#relabel)
* [Lapis](#lapis)
* [lua-parser](#lua-parser)

# relabel
Relabel is [LPegLabel](https://github.com/sqmedeiros/lpeglabel)'s
extension to LPeg's [re module](http://www.inf.puc-rio.br/~roberto/lpeg/re.html),
which provides a regular expression (a.k.a. regex)
inspired syntax to define PEG patterns and grammars.

In total, 30 labels were introduced to the parser. Annotating the
grammars took some thinking at first, but after a while it becomes
easier and you build an intuition. Thankfully, I was given a
short exercise activity on it before tackling the project itself.
I also managed to trigger a bug during the rewrite, which was
quickly fixed by my mentor.

One of the most challenging things for this project was implementing
error recovery. Error recovery is something very tricky and hard,
if not impossible, to perfect. Aside from the time taken to think up
of good strategies to employ, I also took quite some time figuring out
how to properly use labeled choices (Lc) and match-time captures (Cmt)
in implementing the different error recovery strategies.

The changes made have already been integrated in the main repository on
GitHub as can be seen in
[the commit log here](https://github.com/sqmedeiros/lpeglabel/commits/master?author=undecidabot).
The branch implementing error recovery can be found on
[a separate branch on the same repository](https://github.com/sqmedeiros/lpeglabel/commits/relabel-recovery?author=undecidabot).
A report detailing the changes is
[available here](https://github.com/undecidabot/lpeglabel-gsoc-2016/raw/master/relabel.pdf).

A sample of the new error messages is shown below:
```
L1:C17: missing closing ')'
('p' ('q' / 'r')
^
```

# Lapis
[Lapis](https://github.com/leafo/lapis) is a web framework written
in [MoonScript](http://moonscript.org/), a language which compiles
into Lua. Lapis was chosen since it was a fairly popular project and
because the author was open to the idea of merging it, which would help
give us a better idea of how well it works in the practice.

The PEGs in Lapis are quite small, but essential! Lapis uses LPeg
to parse the URL patterns and also some other minor things like a subset
of SQL. For this rewrite, those two parsers were rewritten
and error recovery was not implemented since the expected input is
short enough not to need it.

In total, 12 labels were introduced for the two parsers.
The changes can be viewed in [this pull request](https://github.com/leafo/lapis/pull/445)
sent in the middle of June and also
[this short report](https://github.com/undecidabot/lpeglabel-gsoc-2016/raw/master/lapis.pdf)
detailing the changes made (including examples for the different
labels / errors introduced). Unfortunately, the author seems to be
preoccupied with other matters and has not had the time to review and
merge the pull request.

# lua-parser
[Lua-parser](https://github.com/andremm/lua-parser) is a complete
Lua 5.3 parser written with LPeg. Among the three projects, this one
had the biggest and most complex grammar. In fact, LPegLabel had to be
updated to be able to throw all the labels (LPegLabel originally only
supported up to 64 different labels; now it supports up to 255 labels).
Unsurprisingly, this also took the most time to complete.

In total, 75 labels were introduced to the parser. Like relabel,
error recovery was also implemented for this project. Most of the time,
the parser would simply skip the line after encountering an error.
However, to be honest, I'm not fully satisfied with it yet. It annoys me
that recovery can sometimes introduce false or misleading errors,
but it really is a challenging problem to solve. Even well-known
compilers like `gcc` and `javac` have not perfected this (try mispelling
"for" as "fro" to see what I mean).

The pull request for the changes can be
[found here](https://github.com/andremm/lua-parser/pull/3),
and a branch implementing error recovery can be
[found here](https://github.com/undecidabot/lua-parser/tree/error-recovery).
A copy of the report detailing the changes is also
[available here](https://github.com/undecidabot/lpeglabel-gsoc-2016/raw/master/lua-parser.pdf).

A sample of the difference in error reporting is shown below.

Example code with syntax error:
```
for i=1,10, do end
```

Original error message:
```
test.lua:1:13: syntax error, unexpected 'do', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '~', '#', '-', 'not'
```

New error message:
```
test.lua:1:13: syntax error, expected a step expression for the numeric range after ','
```

In addition to the labels and recovery, some refactoring and clean-up
work was also done. The grammar now follows an arguably more readable
top-down order instead of the original bottom-up order. Some additions
and bug fixing were also done in the handling of escape codes.

# Pegastify
While working on the documentation of lua-parser, I came up with a
tool called [pegastify](https://github.com/undecidabot/pegastify)
(name subject to change in the future) to help me understand the
code describing the grammar of Lua. Pegastify converts LPeg code
into an abstract syntax tree (AST) of the PEG, which can be pretty
printed following the re syntax.

Although the tool still needs more work (especially in tests,
documentation, some additional features, and clean-up), it was more than
enough in helping document and understand the grammar. It also gave me
a taste of lua-parser since it uses lua-parser to parse the code!
Hopefully, I'll find time soon to make it usable by others.

# My Experience
Overall I've had a really great experience in this summer of code.
I was very happy to be able to work for an organization focused
on programming languages, my favorite topic in computer science.

For the first time, I was able to experience what it really is like
to work with others on an open source project. I was able to collaborate
with other people, whom I am unfortunately unable to meet in person.
Working at home also made me realize how much discipline one needs
to get stuff done.

I was also able to develop a better appreciation of documentation and
testing, which I never developed in my school projects since they were
mostly small and not meant to be maintained. Thankfully, the code of
the projects I worked on were readable and had a comprehensive test suite.
After learning a few idioms of Lua, I had no problem in editing the code
and could do so without fear of breaking things.

# Conclusion
LPegLabel is still quite young, but the this project already
proves that it has the potential to greatly improve error messages.
With a little more exposure and tests in the real world, we can
find out how else it can improve. Perhaps, someday it will even be
merged with LPeg.

I'd like to end by thanking
[Professor Sérgio Medeiros, PhD](https://sites.google.com/site/sqmedeiros/)
for being a very responsive, helpful, understanding, and invaluable mentor
throughout the whole summer of code. I would also like to thank
LabLua and Google for giving me the opportunity to work on this project
(and also the monetary benefits of course hehe).