-
Notifications
You must be signed in to change notification settings - Fork 165
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fmt: Start working on format_args!() parser
This commit adds a base class for parsing the various constructs of a Rust format string, according to the grammar in the reference: https://doc.rust-lang.org/std/fmt/index.html#syntax gcc/rust/ChangeLog: * Make-lang.in: Compile rust-fmt object * ast/rust-fmt.cc: New file. * ast/rust-fmt.h: New file.
- Loading branch information
1 parent
2c862b9
commit 43d188f
Showing
3 changed files
with
217 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// Copyright (C) 2020-2023 Free Software Foundation, Inc. | ||
|
||
// This file is part of GCC. | ||
|
||
// GCC is free software; you can redistribute it and/or modify it under | ||
// the terms of the GNU General Public License as published by the Free | ||
// Software Foundation; either version 3, or (at your option) any later | ||
// version. | ||
|
||
// GCC is distributed in the hope that it will be useful, but WITHOUT ANY | ||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
// for more details. | ||
|
||
// You should have received a copy of the GNU General Public License | ||
// along with GCC; see the file COPYING3. If not see | ||
// <http://www.gnu.org/licenses/>. | ||
|
||
#include "rust-fmt.h" | ||
|
||
namespace Rust { | ||
tl::expected<Fmt, Fmt::Error> | ||
Fmt::parse_fmt_string (Fmt::Input input) | ||
{ | ||
return Fmt (); | ||
} | ||
|
||
Fmt::ParseResult<tl::optional<Fmt::Format>> | ||
Fmt::maybe_format (Fmt::Input input) | ||
{ | ||
tl::optional<Fmt::Format> none = tl::nullopt; | ||
|
||
return Fmt::Result (input, none); | ||
} | ||
|
||
Fmt::ParseResult<Fmt::Format> | ||
Fmt::format (Input input) | ||
{ | ||
return Fmt::Result (input, Format ()); | ||
} | ||
|
||
Fmt::ParseResult<Fmt::Argument> | ||
Fmt::argument (Input input) | ||
{ | ||
return Fmt::Result (input, Argument ()); | ||
} | ||
|
||
Fmt::ParseResult<Fmt::FormatSpec> | ||
Fmt::format_spec (Input input) | ||
{ | ||
return Fmt::Result (input, FormatSpec ()); | ||
} | ||
|
||
Fmt::ParseResult<Fmt::Fill> | ||
Fmt::fill (Input input) | ||
{ | ||
return Fmt::Result (input, Fill ()); | ||
} | ||
|
||
Fmt::ParseResult<Fmt::Align> | ||
Fmt::align (Input input) | ||
{ | ||
switch (input[0]) | ||
{ | ||
case '<': | ||
return Fmt::Result (input.substr (1), Align::Left); | ||
case '^': | ||
return Fmt::Result (input.substr (1), Align::Top); | ||
case '>': | ||
return Fmt::Result (input.substr (1), Align::Right); | ||
default: | ||
// TODO: Store the character here | ||
// TODO: Can we have proper error locations? | ||
// TODO: Maybe we should use a Rust::Literal string instead of a string | ||
return tl::make_unexpected (Error::Align); | ||
} | ||
} | ||
|
||
Fmt::ParseResult<Fmt::Sign> | ||
Fmt::sign (Input input) | ||
{ | ||
switch (input[0]) | ||
{ | ||
case '+': | ||
return Fmt::Result (input.substr (1), Sign::Plus); | ||
case '-': | ||
return Fmt::Result (input.substr (1), Sign::Minus); | ||
default: | ||
// TODO: Store the character here | ||
// TODO: Can we have proper error locations? | ||
// TODO: Maybe we should use a Rust::Literal string instead of a string | ||
return tl::make_unexpected (Error::Sign); | ||
} | ||
} | ||
|
||
} // namespace Rust |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
// Copyright (C) 2020-2023 Free Software Foundation, Inc. | ||
|
||
// This file is part of GCC. | ||
|
||
// GCC is free software; you can redistribute it and/or modify it under | ||
// the terms of the GNU General Public License as published by the Free | ||
// Software Foundation; either version 3, or (at your option) any later | ||
// version. | ||
|
||
// GCC is distributed in the hope that it will be useful, but WITHOUT ANY | ||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
// for more details. | ||
|
||
// You should have received a copy of the GNU General Public License | ||
// along with GCC; see the file COPYING3. If not see | ||
// <http://www.gnu.org/licenses/>. | ||
|
||
#ifndef RUST_FMT_H | ||
#define RUST_FMT_H | ||
|
||
#include "expected.h" | ||
#include "optional.h" | ||
#include "rust-ast.h" | ||
#include "rust-system.h" | ||
|
||
namespace Rust { | ||
|
||
/** | ||
* This class implements the parsing of Rust format strings according to the | ||
* grammar here: https://doc.rust-lang.org/std/fmt/index.html#syntax | ||
*/ | ||
// TODO: Are there features that are only present in specific Rust editions? | ||
class Fmt | ||
{ | ||
public: | ||
// TODO: Keep location information | ||
// TODO: Switch to a Rust::AST::Literal here | ||
using Input = std::string; | ||
|
||
enum class Error | ||
{ | ||
Align, | ||
Sign, | ||
}; | ||
|
||
template <typename T> class Result | ||
{ | ||
public: | ||
explicit Result (Input remaining_input, T result) | ||
: remaining_input (remaining_input), result (result) | ||
{} | ||
|
||
private: | ||
Input remaining_input; | ||
T result; | ||
}; | ||
|
||
// FIXME: Do not use an owned string here | ||
static tl::expected<Fmt, Fmt::Error> parse_fmt_string (Input input); | ||
|
||
private: | ||
// the parse functions should return the remaining input as well as the | ||
// expected node let's look at nom | ||
// TODO: no string view :( use an owned string for now? | ||
|
||
template <typename T> using ParseResult = tl::expected<Result<T>, Error>; | ||
|
||
struct Format | ||
{ | ||
}; | ||
|
||
struct Argument | ||
{ | ||
enum struct Kind | ||
{ | ||
Integer, | ||
Identifier, | ||
} kind; | ||
|
||
int integer; | ||
Identifier identifier; | ||
}; | ||
|
||
struct FormatSpec | ||
{ | ||
}; | ||
|
||
struct Fill | ||
{ | ||
char to_fill; | ||
}; | ||
|
||
enum class Align | ||
{ | ||
Left, | ||
Top, | ||
Right | ||
}; | ||
|
||
enum class Sign | ||
{ | ||
Plus, | ||
Minus | ||
}; | ||
|
||
// let's do one function per rule in the BNF | ||
static ParseResult<std::string> text (Input input); | ||
static ParseResult<tl::optional<Format>> maybe_format (Input input); | ||
static ParseResult<Format> format (Input input); | ||
static ParseResult<Argument> argument (Input input); | ||
static ParseResult<FormatSpec> format_spec (Input input); | ||
static ParseResult<Fill> fill (Input input); | ||
static ParseResult<Align> align (Input input); | ||
static ParseResult<Sign> sign (Input input); | ||
}; | ||
|
||
} // namespace Rust | ||
|
||
#endif // ! RUST_FMT_H |