Commit Graph
18 Commits
Author SHA1 Message Date
Richard Smith 9325b50cfe Make numeric literal parsing interface more value-oriented. (#407)
Instead of exposing a stateful Parser type, expose only the result of
its parsing action. This also makes the numeric literal code better
mirror the string literal code.
2021-03-22 15:39:44 -07:00
Richard Smith 9400c1c8ae Switch from manually tracking whether we've emitted any errors to asking the diagnostics machinery. (#406) 2021-03-22 14:01:01 -07:00
Richard Smith 1e6c7e3963 Add sentinel Eof token at the end of the tokenized buffer. (#388)
This has two goals:

1) It allows us to simplify and remove special cases from the parser:
   when we expect a particular token next, we can just check for it
   without needing a special case for end-of-file.

2) It gives us a token to use as a position when emitting diagnostics at
   the end of the file.

Centralize all updating of `position` to `Consume` and `SkipTo`, so that we can in a single place ensure that we never go past the EOF token.
2021-03-18 21:39:10 -07:00
Richard Smith d1757d9979 Add location information to diagnostics. (#385)
Add simple mocking and testing of diagnostic emission to ensure this
works.
2021-03-18 21:05:54 -07:00
Richard Smith ae9ca945b9 Rename {String,Numeric}LiteralToken -> Lexed{String,Numeric}Literal. (#373)
This avoids using a name too similar to Token::StringLiteral (the token
kind) and TokenizedBuffer::Token (which is not related to these
classes).
2021-03-16 12:42:52 -07:00
Richard Smith 97bb6f4e80 Factor out character set handling into a separate file. (#352) 2021-03-09 12:38:46 -08:00
Richard Smith 67ee1fcaa7 Initial support for string literals, following #199 (#309) 2021-03-08 20:33:40 -08:00
Richard Smith 9a873b46de Move numeric literal parsing out into its own files. (#326) 2021-03-04 19:33:08 -08:00
Chandler Carruth cd57024042 Clean up more issues after running clang-format. (#310) 2021-02-26 19:18:40 -08:00
Richard Smith e5335efb44 Simplify error reporting interface (#291) 2021-02-26 18:04:53 -08:00
Richard SmithandChandler Carruth 7eaad4eba0 Use a proof-of-work return type for Lex* functions (#290)
Use a safer return type for the Lex* functions, that requires us to
provide a Token as proof that we lexed something.

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2021-02-26 17:51:28 -08:00
Richard Smith a8e4a69328 Initial lexing support for real literals following #143. (#273) 2021-02-26 17:34:01 -08:00
Richard Smith bbaa0e788c Update comment lexing to match #198. (#292)
Require a space after a `//`, and recognize but reject a `//` that follows non-whitespace text in the same line. Remove DocComment token kind that ended up not being part of the design.
2021-02-25 16:16:08 -08:00
Chandler Carruth b302c50013 Run clang-format over these inputs with the correct style configuration. (#278) 2021-02-22 17:16:27 -08:00
Richard Smith 7670b6377c Initial lexing support for integer literals following #143. (#269) 2021-02-19 14:01:55 -08:00
Chandler Carruth d4a2d435b8 Enable most relevant clang-tidy checks and fix uncovered issues. (#220)
Most of these were fixed automatically (including things like adding
`[[nodiscard]]` and such). A number of others required manual edits.
I think all of them were pretty nice improvements.

There were a few places where the issues really stem from external
constraints and I've disabled the checks: GoogleTest macros or the
specific LibFuzzer entry points.

The only other places I disabled are the implicit conversions to
a private `enum` in the classes wrapping those `enum`s. These implicit
conversions are necessarily implicit to serve their only purpose:
enabling their use in `switch` statements and `case` labels. When these
were highlighted, it showed that one of these was actually converting to
an *`int`*. I've switched that to use the private `enum` instead as
doing so is important to enable warnings on non-covering `switch`
statements over than `enum`. And indeed, there is a `switch` that was
was implicitly relying on falling through in this way, so I've added the
explicit documentation of the intentional pattern to address that
warning.

Sorry this is so large, all of this somewhat fell out of enabling the
`clang-tidy` checks. If it is too difficult to review as lump, I can
work on breaking it apart as needed. Just let me know.
2020-12-08 14:43:37 -08:00
Chandler Carruth 27386db279 Require braces on conditions and loops. (#218)
The rationale and rule for this was added in #194 to the C++ style guide
we are using for Carbon.

I've applied the automated fixes from running `clang-tidy` over all the
code, and then run `clang-format` afterward.

There are a few places where `clang-format` fixed a formatting issue
that snuck through in prior commits. These were rare enough that it
didn't seem worth splitting them out into a separate change.
2020-12-08 02:03:43 -08:00
Chandler CarruthandJon Meow 3995fc2d6c Merge lexer from the toolchain repository. (#213)
The only change here is to update the fuzzer build extension path.

The main original commit message:

> Add an initial lexer. (#17)
>
> The specific logic here hasn't been updated to track the latest
> discussed changes, much less implement many aspects of things like
> Unicode support.
>
> However, this should lay out a reasonable framework and set of APIs.
> It gives an idea of the overall lexer architecture being proposed. The
> actual lexing algorithm is a relatively boring and naive hand written
> loop. It may make sense to replace this with something generated or
> other more advanced approach in the future, getting the implementation
> right was not the primary goal here. Instead, the focus was entirely
> on the architecture, encapsulation, APIs, and the testing
> infrastructure.
>
> The architecture of the lexer differs from "classical" high
> performance lexers in compilers. A high level summary:
>
> -   It is eager rather than lazy, lexing an entire file.
> -   Tokens intrinsically know their source location.
> -   Grouping lexical symbols are tracked within the lexer.
> -   Indentation is tracked within the lexer.
>
> Tracking of grouping and indentation is intended to simplify the
> strategies used for recovery of mismatched grouping tokens, and
> eventually use indentation.
>
> Folding source location into the token itself simplifies the data
> structures significantly, and doesn't lose any fidelity due to the
> absence of a preprocessor with token pasting.
>
> The fact that this is an eager lexer instead of a lazy lexer is
> designed to simplify the implementation and testing of the lexer (and
> subsequent components). There is no reason to expect Carbon to lex so
> many tokens that there are significant locality advantages of lazy
> lexing. Moreover, if we want comparable performance benefits, I think
> pipelining is a much more promising architecture than laziness. For
> now, the simplicity is a huge win.
>
> Being eager also makes it easy for us to use extremely dense memory
> encodings for the information about lexed tokens. Everything is
> created in a dense array, and small indices are used to identify each
> token within the array.
>
> There is a fuzzer included here that we have run extensively over the
> code, but currently toolchain bugs and Bazel limitations prevent it
> from easily building. I'm hoping myself or someone else can push on
> this soon and enable the fuzzer to at least build if not run fuzz
> tests automatically. We have a significant fuzzing corpus that I'll
> add in a subsequent commit as well.

This also includes the fuzzer whose commit message was:

> Add fuzz testing infrastructure and the lexer's fuzzer. (#21)
>
> This adds a fairly simple `cc_fuzz_test` macro that is specialized for
> working with LLVM's LibFuzzer. In addition to building the fuzzer
> binary with the toolchain's `fuzzer` feature, it also sets up the test
> execution to pass the corpus as file arguments which is a simple
> mechanism to enable regression testing against the fuzz corpus.
>
> I've included an initial fuzzer corpus as well. To run the fuzzer in
> an open ended fashion, and build up a larger corpus:
> ```shell
> mkdir /tmp/new_corpus
> cp lexer/fuzzer_corpus/* /tmp/new_corpus
> ./bazel-bin/lexer/tokenized_buffer_fuzzer /tmp/new_corpus
> ```
>
> You can parallelize the fuzzer by adding `-jobs=N` for N threads. For
> more details about running fuzzers, see the documentation:
> http://llvm.org/docs/LibFuzzer.html
>
> To minimize and merge any interesting new inputs:
> ```shell
> ./bazel-bin/lexer/tokenized_buffer_fuzzer -merge=1 \
>     lexer/fuzzer_corpus /tmp/new_corpus
> ```

Co-authored-by: Jon Meow <46229924+jonmeow@users.noreply.github.com>
2020-12-08 01:49:25 -08:00