Skip to content

Commit 5c254c1

Browse files
committed
Simplify the PEG.
This commit simplifies the PEG a little: * Make some rules non-atomic where applicable. * Shuffle the rule definitions to better group related rules. * Rename some rules to be more descriptive.
1 parent d191ddc commit 5c254c1

4 files changed

Lines changed: 95 additions & 96 deletions

File tree

crates/wac-parser/src/ast.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@ struct EndOfInput;
113113
#[derive(Debug, Clone, FromPest)]
114114
#[pest_ast(rule(Rule::Document))]
115115
pub struct Document<'a> {
116-
/// The statements in the document.
117-
pub statements: Vec<Statement<'a>>,
116+
/// The top-level statements in the document.
117+
pub statements: Vec<TopLevelStatement<'a>>,
118118
_eoi: EndOfInput,
119119
}
120120

@@ -208,32 +208,32 @@ impl AstDisplay for Document<'_> {
208208

209209
display!(Document);
210210

211-
/// Represents a statement in the AST.
211+
/// Represents a top-level statement in the AST.
212212
#[derive(Debug, Clone, FromPest)]
213-
#[pest_ast(rule(Rule::Statement))]
214-
pub struct Statement<'a> {
213+
#[pest_ast(rule(Rule::TopLevelStatement))]
214+
pub struct TopLevelStatement<'a> {
215215
/// The doc comments for the statement.
216216
pub docs: Vec<DocComment<'a>>,
217-
/// The statement kind.
218-
pub kind: StatementKind<'a>,
217+
/// The statement.
218+
pub stmt: Statement<'a>,
219219
}
220220

221-
impl AstDisplay for Statement<'_> {
221+
impl AstDisplay for TopLevelStatement<'_> {
222222
fn fmt(&self, f: &mut fmt::Formatter<'_>, indenter: &mut Indenter) -> fmt::Result {
223223
for doc in &self.docs {
224224
doc.fmt(f, indenter)?;
225225
}
226226

227-
self.kind.fmt(f, indenter)
227+
self.stmt.fmt(f, indenter)
228228
}
229229
}
230230

231-
display!(Statement);
231+
display!(TopLevelStatement);
232232

233-
/// Represents a statement kind in the AST.
233+
/// Represents a statement in the AST.
234234
#[derive(Debug, Clone, FromPest)]
235-
#[pest_ast(rule(Rule::StatementKind))]
236-
pub enum StatementKind<'a> {
235+
#[pest_ast(rule(Rule::Statement))]
236+
pub enum Statement<'a> {
237237
/// An import statement.
238238
Import(ImportStatement<'a>),
239239
/// A type statement.
@@ -244,7 +244,7 @@ pub enum StatementKind<'a> {
244244
Export(ExportStatement<'a>),
245245
}
246246

247-
impl AstDisplay for StatementKind<'_> {
247+
impl AstDisplay for Statement<'_> {
248248
fn fmt(&self, f: &mut fmt::Formatter<'_>, indenter: &mut Indenter) -> fmt::Result {
249249
match self {
250250
Self::Import(import) => import.fmt(f, indenter),
@@ -255,7 +255,7 @@ impl AstDisplay for StatementKind<'_> {
255255
}
256256
}
257257

258-
display!(StatementKind);
258+
display!(Statement);
259259

260260
/// Represents an identifier in the AST.
261261
#[derive(Debug, Clone, FromPest)]

crates/wac-parser/src/ast/type.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,8 +1014,8 @@ display!(InterfaceBody);
10141014
pub struct InterfaceItem<'a> {
10151015
/// The doc comments for the interface item.
10161016
pub docs: Vec<DocComment<'a>>,
1017-
/// The interface item kind.
1018-
pub kind: InterfaceItemKind<'a>,
1017+
/// The interface item statement.
1018+
pub stmt: InterfaceItemStatement<'a>,
10191019
}
10201020

10211021
impl AstDisplay for InterfaceItem<'_> {
@@ -1024,16 +1024,16 @@ impl AstDisplay for InterfaceItem<'_> {
10241024
doc.fmt(f, indenter)?;
10251025
}
10261026

1027-
self.kind.fmt(f, indenter)
1027+
self.stmt.fmt(f, indenter)
10281028
}
10291029
}
10301030

10311031
display!(InterfaceItem);
10321032

1033-
/// Represents an interface item kind in the AST.
1033+
/// Represents an interface item statement in the AST.
10341034
#[derive(Debug, Clone, FromPest)]
1035-
#[pest_ast(rule(Rule::InterfaceItemKind))]
1036-
pub enum InterfaceItemKind<'a> {
1035+
#[pest_ast(rule(Rule::InterfaceItemStatement))]
1036+
pub enum InterfaceItemStatement<'a> {
10371037
/// The item is a use statement.
10381038
Use(Box<UseStatement<'a>>),
10391039
/// The item is a value type statement.
@@ -1042,7 +1042,7 @@ pub enum InterfaceItemKind<'a> {
10421042
Export(InterfaceExportStatement<'a>),
10431043
}
10441044

1045-
impl AstDisplay for InterfaceItemKind<'_> {
1045+
impl AstDisplay for InterfaceItemStatement<'_> {
10461046
fn fmt(&self, f: &mut fmt::Formatter<'_>, indenter: &mut Indenter) -> fmt::Result {
10471047
match self {
10481048
Self::Use(u) => u.fmt(f, indenter),
@@ -1052,7 +1052,7 @@ impl AstDisplay for InterfaceItemKind<'_> {
10521052
}
10531053
}
10541054

1055-
display!(InterfaceItemKind);
1055+
display!(InterfaceItemStatement);
10561056

10571057
/// Represents a use statement in the AST.
10581058
#[derive(Debug, Clone, FromPest)]
@@ -1219,8 +1219,8 @@ display!(WorldBody);
12191219
pub struct WorldItem<'a> {
12201220
/// The doc comments for the world item.
12211221
pub docs: Vec<DocComment<'a>>,
1222-
/// The world item kind.
1223-
pub kind: WorldItemKind<'a>,
1222+
/// The world item statement.
1223+
pub stmt: WorldItemStatement<'a>,
12241224
}
12251225

12261226
impl AstDisplay for WorldItem<'_> {
@@ -1229,16 +1229,16 @@ impl AstDisplay for WorldItem<'_> {
12291229
doc.fmt(f, indenter)?;
12301230
}
12311231

1232-
self.kind.fmt(f, indenter)
1232+
self.stmt.fmt(f, indenter)
12331233
}
12341234
}
12351235

12361236
display!(WorldItem);
12371237

1238-
/// Represents a world item kind in the AST.
1238+
/// Represents a world item statement in the AST.
12391239
#[derive(Debug, Clone, FromPest)]
1240-
#[pest_ast(rule(Rule::WorldItemKind))]
1241-
pub enum WorldItemKind<'a> {
1240+
#[pest_ast(rule(Rule::WorldItemStatement))]
1241+
pub enum WorldItemStatement<'a> {
12421242
/// The item is a use statement.
12431243
Use(Box<UseStatement<'a>>),
12441244
/// The item is a value type statement.
@@ -1251,7 +1251,7 @@ pub enum WorldItemKind<'a> {
12511251
Include(WorldIncludeStatement<'a>),
12521252
}
12531253

1254-
impl AstDisplay for WorldItemKind<'_> {
1254+
impl AstDisplay for WorldItemStatement<'_> {
12551255
fn fmt(&self, f: &mut fmt::Formatter<'_>, indenter: &mut Indenter) -> fmt::Result {
12561256
match self {
12571257
Self::Use(u) => u.fmt(f, indenter),
@@ -1263,7 +1263,7 @@ impl AstDisplay for WorldItemKind<'_> {
12631263
}
12641264
}
12651265

1266-
display!(WorldItemKind);
1266+
display!(WorldItemStatement);
12671267

12681268
/// Represents a world import statement in the AST.
12691269
#[derive(Debug, Clone, FromPest)]

crates/wac-parser/src/parser.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ mod pest {
2121
Self::LineComment => "line comment",
2222
Self::BlockComment => "block comment",
2323

24-
Self::Document | Self::Statement | Self::StatementKind => "statement",
24+
Self::Document | Self::TopLevelStatement | Self::Statement => "statement",
2525
Self::ImportStatement => "import statement",
2626
Self::TypeStatement => "type statement",
2727
Self::ValueTypeStatement => "value type statement",
@@ -74,12 +74,12 @@ mod pest {
7474

7575
Self::InterfaceBody => "interface body",
7676
Self::InterfaceItem => "interface item",
77-
Self::InterfaceItemKind => "interface item kind",
77+
Self::InterfaceItemStatement => "interface item statement",
7878
Self::InterfaceExportStatement => "interface export statement",
7979

8080
Self::WorldBody => "world body",
8181
Self::WorldItem => "world item",
82-
Self::WorldItemKind => "world item kind",
82+
Self::WorldItemStatement => "world item statement",
8383
Self::WorldImportStatement => "world import statement",
8484
Self::WorldExportStatement => "world export statement",
8585
Self::WorldItemDecl => "world item declaration",

crates/wac-parser/wac.pest

Lines changed: 61 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
// Top-level document rule
2-
Document = { SOI ~ Statement* ~ EOI }
2+
Document = { SOI ~ TopLevelStatement* ~ EOI }
33

44
// Top-level statements
5-
Statement = ${ DocComment* ~ WHITESPACE* ~ StatementKind }
6-
StatementKind = !{ ImportStatement | TypeStatement | LetStatement | ExportStatement }
5+
TopLevelStatement = { DocComment* ~ Statement }
6+
Statement = { ImportStatement | TypeStatement | LetStatement | ExportStatement }
77

88
// Import statement
99
ImportStatement = ${ ImportKeyword ~ DelimitingSpace+ ~ Ident ~ (DelimitingSpace+ ~ WithClause)? ~ DelimitingSpace* ~ Colon ~ DelimitingSpace* ~ ImportType ~ DelimitingSpace* ~ Semicolon }
@@ -14,32 +14,57 @@ PackageName = ${ Ident ~ (":" ~ Ident)+ }
1414
PackageVersion = { (ASCII_ALPHANUMERIC | "." | "-" | "+")+ }
1515

1616
// Type statement
17-
TypeStatement = !{ InterfaceDecl | WorldDecl | ValueTypeStatement }
18-
ValueTypeStatement = { ResourceDecl | VariantDecl | RecordDecl | FlagsDecl | EnumDecl | TypeAlias }
19-
ResourceDecl = ${ ResourceKeyword ~ DelimitingSpace+ ~ Ident ~ DelimitingSpace* ~ ResourceBody }
20-
ResourceBody = !{ Semicolon | (OpenBrace ~ (ResourceMethod ~ Semicolon)+ ~ CloseBrace) }
21-
VariantDecl = ${ VariantKeyword ~ DelimitingSpace+ ~ Ident ~ DelimitingSpace* ~ VariantBody }
22-
VariantBody = !{ OpenBrace ~ VariantCase ~ ("," ~ VariantCase)* ~ ","? ~ CloseBrace }
23-
VariantCase = { Ident ~ VariantType? }
24-
VariantType = { OpenParen ~ Type ~ CloseParen }
25-
RecordDecl = ${ RecordKeyword ~ DelimitingSpace+ ~ Ident ~ DelimitingSpace* ~ RecordBody }
26-
RecordBody = !{ OpenBrace ~ NamedType ~ ("," ~ NamedType)* ~ ","? ~ CloseBrace }
27-
FlagsDecl = ${ FlagsKeyword ~ DelimitingSpace+ ~ Ident ~ DelimitingSpace* ~ FlagsBody }
28-
FlagsBody = !{ OpenBrace ~ Ident ~ ("," ~ Ident)* ~ ","? ~ CloseBrace }
29-
EnumDecl = ${ EnumKeyword ~ DelimitingSpace+ ~ Ident ~ DelimitingSpace* ~ EnumBody }
30-
EnumBody = !{ OpenBrace ~ Ident ~ ("," ~ Ident)* ~ ","? ~ CloseBrace }
31-
TypeAlias = ${ TypeKeyword ~ DelimitingSpace+ ~ Ident ~ DelimitingSpace* ~ Equals ~ DelimitingSpace* ~ TypeAliasKind ~ DelimitingSpace* ~ Semicolon }
32-
TypeAliasKind = !{ FuncType | Type }
33-
ResourceMethod = { Constructor | Method }
34-
Constructor = { ConstructorKeyword ~ ParamList }
35-
Method = { Ident ~ Colon ~ StaticKeyword? ~ FuncTypeRef }
36-
FuncTypeRef = { Ident | FuncType }
37-
FuncType = { FuncKeyword ~ ParamList ~ ResultList? }
38-
ParamList = { OpenParen ~ (NamedType ~ ("," ~ NamedType)* ~ ","?)? ~ CloseParen }
39-
ResultList = { Arrow ~ (NamedResultList | Type) }
40-
NamedResultList = { OpenParen ~ (NamedType ~ ("," ~ NamedType)* ~ ","?)? ~ CloseParen }
41-
NamedType = { Ident ~ Colon ~ Type }
42-
Type = {
17+
TypeStatement = { InterfaceDecl | WorldDecl | ValueTypeStatement }
18+
InterfaceDecl = ${ InterfaceKeyword ~ DelimitingSpace+ ~ Ident ~ DelimitingSpace* ~ InterfaceBody }
19+
InterfaceBody = !{ OpenBrace ~ InterfaceItem* ~ CloseBrace }
20+
InterfaceItem = { DocComment* ~ InterfaceItemStatement }
21+
InterfaceItemStatement = { UseStatement | ValueTypeStatement | InterfaceExportStatement }
22+
UseStatement = ${ UseKeyword ~ DelimitingSpace+ ~ UseItems ~ DelimitingSpace* ~ Semicolon }
23+
UseItems = !{ UsePath ~ Dot ~ OpenBrace ~ Ident ~ ("," ~ Ident)* ~ ","? ~ CloseBrace }
24+
UsePath = { PackagePath | Ident }
25+
InterfaceExportStatement = { Ident ~ Colon ~ FuncTypeRef ~ Semicolon }
26+
WorldDecl = ${ WorldKeyword ~ DelimitingSpace+ ~ Ident ~ DelimitingSpace* ~ WorldBody }
27+
WorldBody = !{ OpenBrace ~ WorldItem* ~ CloseBrace }
28+
WorldItem = { DocComment* ~ WorldItemStatement }
29+
WorldItemStatement = { UseStatement | ValueTypeStatement | WorldImportStatement | WorldExportStatement | WorldIncludeStatement }
30+
WorldImportStatement = ${ ImportKeyword ~ DelimitingSpace+ ~ WorldItemDecl ~ DelimitingSpace* ~ Semicolon }
31+
WorldExportStatement = ${ ExportKeyword ~ DelimitingSpace+ ~ WorldItemDecl ~ DelimitingSpace* ~ Semicolon }
32+
WorldItemDecl = !{ WorldNamedItem | InterfaceRef }
33+
WorldNamedItem = { Ident ~ Colon ~ ExternType ~ !Slash }
34+
InterfaceRef = { PackagePath | Ident }
35+
ExternType = { FuncType | InlineInterface | Ident }
36+
InlineInterface = { InterfaceKeyword ~ InterfaceBody }
37+
WorldIncludeStatement = ${ IncludeKeyword ~ DelimitingSpace+ ~ WorldRef ~ DelimitingSpace* ~ WorldIncludeWithClause? ~ DelimitingSpace* ~ Semicolon }
38+
WorldIncludeWithClause = !{ WithKeyword ~ OpenBrace ~ WorldIncludeItem ~ ("," ~ WorldIncludeItem)* ~ ","? ~ CloseBrace }
39+
WorldIncludeItem = ${ Ident ~ DelimitingSpace+ ~ AsKeyword ~ DelimitingSpace+ ~ Ident }
40+
WorldRef = { PackagePath | Ident }
41+
42+
// Value type statement
43+
ValueTypeStatement = { ResourceDecl | VariantDecl | RecordDecl | FlagsDecl | EnumDecl | TypeAlias }
44+
ResourceDecl = ${ ResourceKeyword ~ DelimitingSpace+ ~ Ident ~ DelimitingSpace* ~ ResourceBody }
45+
ResourceBody = !{ Semicolon | (OpenBrace ~ (ResourceMethod ~ Semicolon)+ ~ CloseBrace) }
46+
ResourceMethod = { Constructor | Method }
47+
Constructor = { ConstructorKeyword ~ ParamList }
48+
Method = { Ident ~ Colon ~ StaticKeyword? ~ FuncTypeRef }
49+
VariantDecl = ${ VariantKeyword ~ DelimitingSpace+ ~ Ident ~ DelimitingSpace* ~ VariantBody }
50+
VariantBody = !{ OpenBrace ~ VariantCase ~ ("," ~ VariantCase)* ~ ","? ~ CloseBrace }
51+
VariantCase = { Ident ~ VariantType? }
52+
VariantType = { OpenParen ~ Type ~ CloseParen }
53+
RecordDecl = ${ RecordKeyword ~ DelimitingSpace+ ~ Ident ~ DelimitingSpace* ~ RecordBody }
54+
RecordBody = !{ OpenBrace ~ NamedType ~ ("," ~ NamedType)* ~ ","? ~ CloseBrace }
55+
FlagsDecl = ${ FlagsKeyword ~ DelimitingSpace+ ~ Ident ~ DelimitingSpace* ~ FlagsBody }
56+
FlagsBody = !{ OpenBrace ~ Ident ~ ("," ~ Ident)* ~ ","? ~ CloseBrace }
57+
EnumDecl = ${ EnumKeyword ~ DelimitingSpace+ ~ Ident ~ DelimitingSpace* ~ EnumBody }
58+
EnumBody = !{ OpenBrace ~ Ident ~ ("," ~ Ident)* ~ ","? ~ CloseBrace }
59+
TypeAlias = ${ TypeKeyword ~ DelimitingSpace+ ~ Ident ~ DelimitingSpace* ~ Equals ~ DelimitingSpace* ~ TypeAliasKind ~ DelimitingSpace* ~ Semicolon }
60+
TypeAliasKind = !{ FuncType | Type }
61+
FuncTypeRef = { FuncType | Ident }
62+
FuncType = { FuncKeyword ~ ParamList ~ ResultList? }
63+
ParamList = { OpenParen ~ (NamedType ~ ("," ~ NamedType)* ~ ","?)? ~ CloseParen }
64+
ResultList = { Arrow ~ (NamedResultList | Type) }
65+
NamedResultList = { OpenParen ~ (NamedType ~ ("," ~ NamedType)* ~ ","?)? ~ CloseParen }
66+
NamedType = { Ident ~ Colon ~ Type }
67+
Type = {
4368
U8Keyword
4469
| S8Keyword
4570
| U16Keyword
@@ -60,34 +85,13 @@ Type = {
6085
| Borrow
6186
| Ident
6287
}
63-
Tuple = { TupleKeyword ~ OpenAngle ~ Type ~ ("," ~ Type)* ~ CloseAngle }
64-
List = { ListKeyword ~ OpenAngle ~ Type ~ CloseAngle }
65-
Option = { OptionKeyword ~ OpenAngle ~ Type ~ CloseAngle }
66-
Result = { ResultKeyword ~ SpecifiedResult? }
67-
SpecifiedResult = { OpenAngle ~ OmitType ~ ("," ~ Type)? ~ CloseAngle }
68-
OmitType = { Underscore | Type }
69-
Borrow = { BorrowKeyword ~ OpenAngle ~ Ident ~ CloseAngle }
70-
InterfaceDecl = ${ InterfaceKeyword ~ DelimitingSpace+ ~ Ident ~ DelimitingSpace* ~ InterfaceBody }
71-
InterfaceBody = !{ OpenBrace ~ InterfaceItem* ~ CloseBrace }
72-
InterfaceItem = ${ DocComment* ~ WHITESPACE* ~ InterfaceItemKind }
73-
InterfaceItemKind = !{ UseStatement | ValueTypeStatement | InterfaceExportStatement }
74-
InterfaceExportStatement = { Ident ~ Colon ~ FuncTypeRef ~ Semicolon }
75-
WorldDecl = ${ WorldKeyword ~ DelimitingSpace+ ~ Ident ~ DelimitingSpace* ~ WorldBody }
76-
WorldBody = !{ OpenBrace ~ WorldItem* ~ CloseBrace }
77-
WorldItem = ${ DocComment* ~ WHITESPACE* ~ WorldItemKind }
78-
WorldItemKind = !{ UseStatement | ValueTypeStatement | WorldImportStatement | WorldExportStatement | WorldIncludeStatement }
79-
WorldImportStatement = ${ ImportKeyword ~ DelimitingSpace+ ~ WorldItemDecl ~ DelimitingSpace* ~ Semicolon }
80-
WorldExportStatement = ${ ExportKeyword ~ DelimitingSpace+ ~ WorldItemDecl ~ DelimitingSpace* ~ Semicolon }
81-
WorldItemDecl = !{ WorldNamedItem | InterfaceRef }
82-
WorldNamedItem = ${ Ident ~ DelimitingSpace* ~ Colon ~ DelimitingSpace+ ~ ExternType }
83-
InterfaceRef = { PackagePath | Ident }
84-
ExternType = !{ FuncType | InlineInterface | Ident }
85-
InlineInterface = { InterfaceKeyword ~ InterfaceBody }
86-
87-
WorldIncludeStatement = ${ IncludeKeyword ~ DelimitingSpace+ ~ WorldRef ~ DelimitingSpace* ~ WorldIncludeWithClause? ~ DelimitingSpace* ~ Semicolon }
88-
WorldIncludeWithClause = !{ WithKeyword ~ OpenBrace ~ WorldIncludeItem ~ ("," ~ WorldIncludeItem)* ~ ","? ~ CloseBrace }
89-
WorldIncludeItem = ${ Ident ~ DelimitingSpace+ ~ AsKeyword ~ DelimitingSpace+ ~ Ident }
90-
WorldRef = { PackagePath | Ident }
88+
Tuple = { TupleKeyword ~ OpenAngle ~ Type ~ ("," ~ Type)* ~ CloseAngle }
89+
List = { ListKeyword ~ OpenAngle ~ Type ~ CloseAngle }
90+
Option = { OptionKeyword ~ OpenAngle ~ Type ~ CloseAngle }
91+
Result = { ResultKeyword ~ SpecifiedResult? }
92+
SpecifiedResult = { OpenAngle ~ OmitType ~ ("," ~ Type)? ~ CloseAngle }
93+
OmitType = { Underscore | Type }
94+
Borrow = { BorrowKeyword ~ OpenAngle ~ Ident ~ CloseAngle }
9195

9296
// Let statement
9397
LetStatement = ${ LetKeyword ~ DelimitingSpace+ ~ Ident ~ DelimitingSpace* ~ Equals ~ DelimitingSpace* ~ Expr ~ DelimitingSpace* ~ Semicolon }
@@ -109,11 +113,6 @@ PostfixExpr = { AccessExpr | NamedAccessExpr }
109113
AccessExpr = ${ Dot ~ Ident }
110114
NamedAccessExpr = { OpenBracket ~ String ~ CloseBracket }
111115

112-
// Use statement in interface and world definitinos
113-
UseStatement = ${ UseKeyword ~ DelimitingSpace+ ~ UseItems ~ DelimitingSpace* ~ Semicolon }
114-
UseItems = !{ UsePath ~ Dot ~ OpenBrace ~ Ident ~ ("," ~ Ident)* ~ ","? ~ CloseBrace }
115-
UsePath = { PackagePath | Ident }
116-
117116
// Identifiers
118117
RawIdent = _{ Percent ~ IdentPart ~ (Hyphen ~ IdentPart)* }
119118
Ident = @{ RawIdent | !(Keyword ~ !Hyphen) ~ IdentPart ~ (Hyphen ~ IdentPart)* }

0 commit comments

Comments
 (0)