Skip to content

Commit aaf3790

Browse files
authored
Merge pull request #17 from Tsukuba-Programming-Lab/develop
Release v0.1.1
2 parents 3b21938 + 632cc62 commit aaf3790

File tree

24 files changed

+367
-252
lines changed

24 files changed

+367
-252
lines changed

Cargo.lock

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
[package]
22
name = "parsergen"
3-
version = "0.1.0"
3+
version = "0.1.1"
44
edition = "2021"
55

66
[dependencies]
77
anyhow = { workspace = true }
88
thiserror = { workspace = true }
9-
core = { workspace = true }
10-
algorithm = { workspace = true }
9+
pgen_core = { workspace = true }
10+
pgen_algorithm = { workspace = true }
1111

1212
[dev-dependencies]
1313
serde = { workspace = true }
1414
serde_json = "1.0.117"
1515

1616
[features]
1717
default = []
18-
derive = ["core/derive"]
18+
derive = ["pgen_core/derive"]
1919

2020
[workspace]
2121
resolver = "2"
@@ -31,5 +31,5 @@ thiserror = "1.0.58"
3131
serde = "1.0.197"
3232
regex = "1.10.4"
3333
regex-macro = "0.2.0"
34-
core = { path = "./crates/core" }
35-
algorithm = { path = "./crates/algorithm" }
34+
pgen_core = { package = "core", path = "./crates/core" }
35+
pgen_algorithm = { package = "algorithm", path = "./crates/algorithm" }

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,15 @@ Rust製パーサジェネレータ
1313
```
1414
$ cargo run --example expr
1515
(10+20)/((30*40)-50)
16-
Accepted
16+
Accepted : (Expr (Term (Term (Num "(" (Expr (Expr (Term (Num "10"))) "+" (Term (Num "20"))) ")")) "/" (Num "(" (Expr (Expr (Term (Num "(" (Expr (Term (Term (Num "30")) "*" (Num "40"))) ")"))) "-" (Term (Num "50"))) ")")))
1717
1818
$ cargo run --example expr
1919
10**
20-
Rejected: Error at (0, 3)
20+
-----
21+
1: 10**
22+
^ here
23+
Error at line 1, column 4.
24+
-----
25+
26+
Rejected : Unexpected token "Mul" found
2127
```

crates/algorithm/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "algorithm"
3-
version = "0.1.0"
3+
version = "0.1.1"
44
edition = "2021"
55

66
[dependencies]

crates/algorithm_lr1/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
[package]
22
name = "algorithm_lr1"
3-
version = "0.1.0"
3+
version = "0.1.1"
44
edition = "2021"
55

66
[dependencies]
77
anyhow = { workspace = true }
88
thiserror = { workspace = true }
99
serde = { workspace = true, features = ["derive"] }
1010
itertools = "0.12.1"
11-
core = { path = "../core", features = ["derive"] }
11+
pgen_core = { package = "core", path = "../core", features = ["derive"] }

crates/algorithm_lr1/src/builder.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::marker::PhantomData;
55
use serde::{Serialize, Deserialize};
66
use itertools::Itertools;
77

8-
use core::cfg::{TokenSet, Syntax, Rule, RuleElem, RuleSet};
8+
use pgen_core::cfg::{TokenSet, Syntax, Rule, RuleElem, RuleSet};
99

1010
#[derive(Debug, Serialize, Deserialize)]
1111
pub(super) enum LRAction<S> {
@@ -37,11 +37,8 @@ where
3737
{
3838
pub fn setup() -> anyhow::Result<Self> {
3939
// 1. Pre-process
40-
let rules = S::try_into()?
41-
.into_iter()
42-
.map(|(rule, _)| rule)
43-
.collect::<Vec<_>>();
44-
let ruleset = RuleSet::from(rules);
40+
let rules = S::into_iter().collect::<Vec<_>>();
41+
let ruleset = S::into_ruleset();
4542
let first_set = ruleset.first_set();
4643

4744
// 2. Generate dummy nonterm
@@ -76,7 +73,7 @@ where
7673
let mut goto_table: Vec<Vec<usize>> = Vec::with_capacity(dfa.0.len());
7774
for _ in 0..dfa.0.len() {
7875
action_table.push(HashMap::from_iter(
79-
T::enum_iter()
76+
T::into_iter()
8077
.map(|token| (token, LRAction::None))
8178
.collect::<Vec<(T, LRAction<S>)>>(),
8279
));
@@ -85,7 +82,6 @@ where
8582
}
8683

8784
// 5. Setup tables
88-
let rule_table: Vec<S> = S::enum_iter().collect();
8985
for lritem_set in &dfa.0 {
9086
for (token, next) in &lritem_set.next {
9187
match &token {
@@ -113,7 +109,7 @@ where
113109
let id = lritem_set.id as usize;
114110
let label = action_table[id].get_mut(&t.0).unwrap();
115111
*label = LRAction::Reduce(
116-
rule_table[item.rule.id as usize],
112+
rules[item.rule.id as usize],
117113
*nonterm_table.get(lhs).unwrap(),
118114
item.rule.rhs.len(),
119115
);
@@ -124,7 +120,7 @@ where
124120
LRAction::Accept
125121
} else {
126122
LRAction::Reduce(
127-
rule_table[item.rule.id as usize],
123+
rules[item.rule.id as usize],
128124
*nonterm_table.get(lhs).unwrap(),
129125
item.rule.rhs.len(),
130126
)

crates/algorithm_lr1/src/driver.rs

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
use core::cfg::{TokenSet, Syntax};
2-
use core::lex::LexIterator;
1+
use pgen_core::cfg::{TokenSet, Syntax};
2+
use pgen_core::lex::Token;
3+
use pgen_core::parse::{SExp, SExpBuilder};
34

4-
use super::builder::{LRAction, LR1Configure};
5+
use crate::error::ParseError;
6+
use crate::builder::{LRAction, LR1Configure};
57

68
pub(super) struct LR1Driver<'a, 'b, T, S> (&'b LR1Configure<'a, T, S>)
79
where
@@ -19,41 +21,45 @@ where
1921

2022
pub fn run<'c>(
2123
&self,
22-
lexer: &mut impl LexIterator<'a, 'c, T>,
23-
) -> anyhow::Result<()> {
24+
lexer: &mut impl Iterator<Item = Token<'a, 'c, T>>,
25+
) -> anyhow::Result<SExp<'a, 'c, T, S>> {
2426
let mut stack = vec![0];
27+
let mut builder = SExpBuilder::new();
2528
loop {
2629
let input = lexer.next();
2730
loop {
2831
let top = stack[stack.len() - 1];
2932
let action = match input {
3033
Some(token) => (
3134
self.0.action_table[top].get(&token.kind).unwrap(),
32-
Some(token.as_str()),
35+
Some(token),
3336
),
3437
None => (
3538
&self.0.eof_action_table[top],
3639
None
3740
),
3841
};
39-
match action.0 {
40-
LRAction::Shift(new_state) => {
42+
match action {
43+
(LRAction::Shift(new_state), Some(token)) => {
4144
stack.push(*new_state);
45+
builder.push(token);
4246
break;
4347
}
44-
LRAction::Reduce(_, goto, elems_cnt) => {
48+
(LRAction::Reduce(tag, goto, elems_cnt), _) => {
4549
stack.truncate(stack.len() - elems_cnt);
4650
stack.push(self.0.goto_table[stack[stack.len() - 1]][*goto]);
51+
builder.wrap(*tag, *elems_cnt);
4752
}
48-
LRAction::None => {
49-
let pos = lexer.pos();
50-
let pos = match action.1 {
51-
Some(raw) => (pos.0, pos.1 - (raw.len() as u32)),
52-
None => pos,
53-
};
54-
return Err(anyhow::anyhow!("Error at {:?}", pos).into());
53+
(LRAction::Accept, _) => {
54+
return builder.build();
5555
}
56-
LRAction::Accept => return Ok(()),
56+
(LRAction::None, Some(token)) => {
57+
return Err(ParseError::new_unexpected_token(token).into());
58+
}
59+
(LRAction::None, None) => {
60+
return Err(ParseError::UnexpectedEOF.into());
61+
}
62+
_ => unreachable!(),
5763
}
5864
}
5965
}

crates/algorithm_lr1/src/error.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use thiserror::Error;
2+
3+
use pgen_core::error::ParseError as SuperParseError;
4+
use pgen_core::cfg::TokenSet;
5+
use pgen_core::lex::Token;
6+
7+
#[derive(Debug, Error)]
8+
pub enum ParseError {
9+
#[error("Unexpected token {actual:?} found")]
10+
UnexpectedToken {
11+
actual: String,
12+
},
13+
#[error("Unexpected EOF")]
14+
UnexpectedEOF,
15+
}
16+
17+
impl ParseError {
18+
pub fn new_unexpected_token<'a, T>(expected: Token<'a, '_, T>) -> SuperParseError
19+
where
20+
T: TokenSet<'a>,
21+
{
22+
let err = ParseError::UnexpectedToken {
23+
actual: format!("{:?}", expected.kind),
24+
};
25+
SuperParseError::from(err).with(expected)
26+
}
27+
}

crates/algorithm_lr1/src/lib.rs

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
mod error;
12
mod builder;
23
mod driver;
34

45
use serde::{Serialize, Deserialize};
56

6-
use core::cfg::{TokenSet, Syntax};
7-
use core::lex::LexIterator;
8-
use core::parse::ParserImpl;
7+
use pgen_core::cfg::{TokenSet, Syntax};
8+
use pgen_core::lex::Token;
9+
use pgen_core::parse::{ParserImpl, SExp};
910

1011
use builder::LR1Configure;
1112
use driver::LR1Driver;
@@ -23,24 +24,23 @@ where
2324
{
2425
type TokenSet = T;
2526
type Syntax = S;
26-
type Output = ();
2727

2828
fn setup() -> anyhow::Result<Self> {
2929
Ok(LR1(LR1Configure::setup()?))
3030
}
3131

3232
fn parse<'b>(
3333
&self,
34-
mut lexer: impl LexIterator<'a, 'b, T>,
35-
) -> anyhow::Result<Self::Output> {
34+
mut lexer: impl Iterator<Item = Token<'a, 'b, T>>,
35+
) -> anyhow::Result<SExp<'a, 'b, T, S>> {
3636
LR1Driver::new(&self.0).run(&mut lexer)
3737
}
3838
}
3939

4040
#[cfg(test)]
4141
mod test {
42-
use core::cfg::{TokenSet, Syntax, Rule, RuleElem};
43-
use core::Parser;
42+
use pgen_core::cfg::{TokenSet, Syntax, Rule, RuleElem};
43+
use pgen_core::Parser;
4444

4545
use super::LR1;
4646

@@ -67,19 +67,14 @@ mod test {
6767
#[derive(Debug, Clone, Copy, Syntax)]
6868
enum TestSyntax {
6969
#[rule("<expr> ::= <expr> Plus <term>")]
70-
ExprPlus,
7170
#[rule("<expr> ::= <expr> Minus <term>")]
72-
ExprMinus,
7371
#[rule("<expr> ::= <term>")]
74-
ExprTerm,
72+
Expr,
7573
#[rule("<term> ::= <term> Mul <num>")]
76-
TermMul,
7774
#[rule("<term> ::= <term> Div <num>")]
78-
TermDiv,
7975
#[rule("<term> ::= <num>")]
80-
TermNum,
76+
Term,
8177
#[rule("<num> ::= BracketL <expr> BracketR")]
82-
NestedNum,
8378
#[rule("<num> ::= Num")]
8479
Num,
8580
}

crates/core/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
[package]
22
name = "core"
3-
version = "0.1.0"
3+
version = "0.1.1"
44
edition = "2021"
55

66
[dependencies]
77
anyhow = { workspace = true }
88
thiserror = { workspace = true }
99
serde = { workspace = true, features = ["derive"]}
1010
regex = { workspace = true }
11-
derive = { package = "core_derive", path = "../core_derive", optional = true }
11+
pgen_core_derive = { package = "core_derive", path = "../core_derive", optional = true }
1212

1313
[features]
1414
default = []
15-
derive = ["dep:derive"]
15+
derive = ["dep:pgen_core_derive"]

0 commit comments

Comments
 (0)