Add WIP Pest grammar
This commit is contained in:
parent
1eed7487ca
commit
b47137d27d
|
@ -8,4 +8,6 @@ license = "GPL-3.0-or-later"
|
|||
[dependencies]
|
||||
console = "0.15.0"
|
||||
logos = "0.12.0"
|
||||
pest = "2"
|
||||
pest_derive = "2"
|
||||
strum = { version="0.24", features=["derive"] }
|
||||
|
|
21
src/lib.rs
21
src/lib.rs
|
@ -1,6 +1,9 @@
|
|||
// Copyright (c) 2022 Marceline Cramer
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#[macro_use]
|
||||
extern crate pest_derive;
|
||||
|
||||
use console::Style;
|
||||
|
||||
pub mod lexer;
|
||||
|
@ -41,6 +44,12 @@ impl ColorTheme {
|
|||
}
|
||||
}
|
||||
|
||||
mod pest_parser {
|
||||
#[derive(Parser)]
|
||||
#[grammar = "sprite.pest"]
|
||||
pub struct SpriteParser;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -58,6 +67,18 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_pest() {
|
||||
use pest::Parser;
|
||||
use pest_parser::{Rule, SpriteParser};
|
||||
let source = include_str!("test/clock.fae");
|
||||
let parsed = SpriteParser::parse(Rule::module, source);
|
||||
match parsed {
|
||||
Ok(ok) => println!("{:#?}", ok),
|
||||
Err(err) => panic!("{}", err),
|
||||
}
|
||||
}
|
||||
|
||||
// TODO use spans to color-code instead of raw tokens, to show original whitespace
|
||||
/*#[test]
|
||||
fn color_file() {
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
// Copyright (c) 2022 Marceline Cramer
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
module = { SOI ~ top_level* ~ EOI }
|
||||
top_level = _{ iface_def | struct_def | impl_block | impl_fn }
|
||||
struct_def = { "struct" ~ identifier ~ member_defs }
|
||||
iface_def = { "interface" ~ identifier ~ iface_defs }
|
||||
impl_block = { "impl" ~ identifier ~ identifier? ~ "{" ~ impl_fn* ~ "}" }
|
||||
impl_fn = { fn_def ~ branch }
|
||||
|
||||
member_defs = _{ "{" ~ "}" | "{" ~ member_def ~ ("," ~ member_def)* ~ ","? ~ "}" }
|
||||
iface_defs = _{ "{" ~ (fn_def ~ ";")* ~ "}" }
|
||||
fn_args = _{ "(" ~ ")" | "(" ~ fn_arg ~ ("," ~ fn_arg)* ~ ")" }
|
||||
|
||||
member_def = { identifier ~ identifier }
|
||||
fn_def = { "mut"? ~ "fn" ~ identifier ~ fn_args ~ identifier? }
|
||||
fn_arg = { identifier ~ identifier? }
|
||||
|
||||
branch = _{ "{" ~ stmt* ~ expr? ~ "}" }
|
||||
stmt = _{ let_stmt | if_stmt | while_stmt | expr ~ ";" }
|
||||
let_stmt = { "let" ~ "mut"? ~ identifier ~ "=" ~ expr ~ ";" }
|
||||
if_stmt = { "if" ~ expr ~ branch ~ ("else" ~ branch)? }
|
||||
while_stmt = { "while" ~ expr ~ branch }
|
||||
|
||||
expr = { term ~ (binary_op ~ term)* }
|
||||
term = { unary_op? ~ val ~ call_args? ~ field* }
|
||||
call_args = { "(" ~ (expr ~ ("," ~ expr)*)? ~ ")" }
|
||||
field = { "." ~ identifier ~ call_args? }
|
||||
val = _{ field | if_expr | identifier | literal | "(" ~ expr ~ ")" }
|
||||
literal = _{ string | float | int }
|
||||
if_expr = { "if" ~ expr ~ branch ~ "else" ~ branch }
|
||||
|
||||
unary_op = _{ op_bool_not | op_bit_not }
|
||||
binary_op = _{
|
||||
op_eq | // match early to prevent shadowing
|
||||
op_add | op_sub | op_mul | op_div | op_assign |
|
||||
op_bool_or | op_bool_and |
|
||||
op_bit_or | op_bit_and | op_bit_xor |
|
||||
op_less_eq | op_less | op_greater_eq | op_greater | op_neq
|
||||
}
|
||||
|
||||
// arithmetic operators
|
||||
op_add = { "+" }
|
||||
op_sub = { "-" }
|
||||
op_mul = { "*" }
|
||||
op_div = { "/" }
|
||||
op_assign = { "=" }
|
||||
|
||||
// boolean operators
|
||||
op_bool_or = { "or" }
|
||||
op_bool_and = { "and" }
|
||||
op_bool_not = { "not" }
|
||||
|
||||
// bitwise operators
|
||||
op_bit_or = { "|" }
|
||||
op_bit_and = { "&" }
|
||||
op_bit_xor = { "^" }
|
||||
op_bit_not = { "~" }
|
||||
|
||||
// comparison operators
|
||||
op_less = { "<" }
|
||||
op_less_eq = { "<=" }
|
||||
op_greater = { ">" }
|
||||
op_greater_eq = { ">=" }
|
||||
op_eq = { "==" }
|
||||
op_neq = { "!=" }
|
||||
|
||||
string = @{ "\"" ~ (!"\"" ~ ANY)* ~ "\"" }
|
||||
bool = { "true" | "false" }
|
||||
int = @{ ("+" | "-")? ~ ASCII_DIGIT+ }
|
||||
float = @{ ASCII_DIGIT+ ~ "." ~ ASCII_DIGIT* | "." ~ ASCII_DIGIT+ }
|
||||
identifier = @{ ("_" | ASCII_ALPHA) ~ ("_" | ASCII_ALPHANUMERIC)* }
|
||||
|
||||
WHITESPACE = _{ " " | "\t" | NEWLINE }
|
||||
COMMENT = _{ "//" ~ (!NEWLINE ~ ANY)* }
|
Loading…
Reference in New Issue