Skip to content

Commit bacaeda

Browse files
committed
feat: add clafer modelling support
1 parent 51cec5e commit bacaeda

8 files changed

Lines changed: 979 additions & 0 deletions

File tree

‎Cargo.lock‎

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

‎Cargo.toml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ anyhow = "1.0.101"
1212
chrono = "0.4.44"
1313
clap = { version = "4.5.59", features = ["derive"] }
1414
git2 = "0.20.4"
15+
pest = "2.8.6"
16+
pest_derive = "2.8.6"
1517
regex = "1.12.3"
1618
serde = { version = "1.0.228", features = ["derive"] }
1719
serde_json = "1.0.149"

‎src/parser.rs‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub mod ast;
2+
pub mod evaluator;
3+
pub mod grammar;

‎src/parser/ast.rs‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#[derive(Debug, Clone)]
2+
pub enum Declaration {
3+
EnumDecl(String, Vec<String>),
4+
Element(Element),
5+
}
6+
7+
#[derive(Debug, Clone)]
8+
pub enum Element {
9+
Clafer(Clafer),
10+
Constraint(Expr),
11+
}
12+
13+
#[derive(Debug, Clone, PartialEq)]
14+
pub enum Expr {
15+
Ref(String),
16+
Not(Box<Expr>),
17+
And(Box<Expr>, Box<Expr>),
18+
Or(Box<Expr>, Box<Expr>),
19+
Xor(Box<Expr>, Box<Expr>),
20+
Implies(Box<Expr>, Box<Expr>),
21+
Iff(Box<Expr>, Box<Expr>),
22+
/// Anything outside the boolean-feature subset (comparisons, arithmetic,
23+
/// joins, literals). Always evaluates to "unknown" during resolution.
24+
Other(String),
25+
}
26+
27+
#[derive(Debug, Clone)]
28+
pub struct Clafer {
29+
pub is_abstract: bool,
30+
pub gcard: Option<String>,
31+
pub name: String,
32+
pub super_type: Option<String>,
33+
pub card: Option<String>,
34+
pub children: Vec<Element>,
35+
}

‎src/parser/clafer-subset.cf‎

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
Module. Module ::= [Declaration] ;
2+
3+
EnumDecl. Declaration ::= "enum" PosIdent "=" [EnumId] ;
4+
ElementDecl. Declaration ::= Element ;
5+
6+
Clafer. Clafer ::= Abstract GCard PosIdent Super Reference Card Init Elements ;
7+
Constraint. Constraint ::= "[" Exp "]" ;
8+
9+
AbstractEmpty. Abstract ::= ;
10+
Abstract. Abstract ::= "abstract" ;
11+
12+
ElementsEmpty. Elements ::= ;
13+
ElementsList. Elements ::= "{" [Element] "}" ;
14+
15+
Subclafer. Element ::= Clafer ;
16+
Subconstraint. Element ::= Constraint ;
17+
18+
SuperEmpty. Super ::= ;
19+
SuperSome. Super ::= ":" Exp8 ;
20+
21+
ReferenceEmpty. Reference ::= ;
22+
ReferenceSet. Reference ::= "->" Exp6 ;
23+
24+
InitEmpty. Init ::= ;
25+
InitConstant. Init ::= "=" Exp ;
26+
27+
GCardEmpty. GCard ::= ;
28+
GCardXor. GCard ::= "xor" ;
29+
GCardOr. GCard ::= "or" ;
30+
GCardMux. GCard ::= "mux" ;
31+
GCardOpt. GCard ::= "opt" ;
32+
GCardInterval. GCard ::= NCard ;
33+
34+
CardEmpty. Card ::= ;
35+
CardLone. Card ::= "?" ;
36+
CardSome. Card ::= "+" ;
37+
CardAny. Card ::= "*" ;
38+
CardNum. Card ::= PosInteger ;
39+
CardInterval. Card ::= NCard ;
40+
41+
NCard. NCard ::= PosInteger ".." ExInteger ;
42+
ExIntegerAst. ExInteger ::= "*" ;
43+
ExIntegerNum. ExInteger ::= PosInteger ;
44+
45+
-- Boolean & Relational Expressions (Precedence modeled via Exp levels)
46+
EIff. Exp ::= Exp "<=>" Exp1 ;
47+
EImplies. Exp1 ::= Exp1 "=>" Exp2 ;
48+
EOr. Exp2 ::= Exp2 "||" Exp3 ;
49+
EXor. Exp3 ::= Exp3 "xor" Exp4 ;
50+
EAnd. Exp4 ::= Exp4 "&&" Exp5 ;
51+
ENeg. Exp5 ::= "!" Exp5 ;
52+
ELt. Exp6 ::= Exp6 "<" Exp7 ;
53+
EGt. Exp6 ::= Exp6 ">" Exp7 ;
54+
EEq. Exp6 ::= Exp6 "=" Exp7 ;
55+
ELte. Exp6 ::= Exp6 "<=" Exp7 ;
56+
EGte. Exp6 ::= Exp6 ">=" Exp7 ;
57+
ENeq. Exp6 ::= Exp6 "!=" Exp7 ;
58+
EIn. Exp6 ::= Exp6 "in" Exp7 ;
59+
ENin. Exp6 ::= Exp6 "not" "in" Exp7 ;
60+
EAdd. Exp7 ::= Exp7 "+" Exp8 ;
61+
ESub. Exp7 ::= Exp7 "-" Exp8 ;
62+
EJoin. Exp8 ::= Exp8 "." Exp9 ;
63+
64+
EQuantExp. Exp9 ::= Quant Exp10 ;
65+
ClaferId. Exp10 ::= PosIdent ;
66+
EInt. Exp10 ::= PosInteger ;
67+
EStr. Exp10 ::= PosString ;
68+
EParens. Exp10 ::= "(" Exp ")" ;
69+
70+
QuantNo. Quant ::= "no" ;
71+
QuantNot. Quant ::= "not" ;
72+
QuantLone. Quant ::= "lone" ;
73+
QuantOne. Quant ::= "one" ;
74+
QuantSome. Quant ::= "some" ;
75+
QuantAll. Quant ::= "all" ;

‎src/parser/clafer.pest‎

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// --- Entry Point ---
2+
module = { SOI ~ declaration* ~ EOI }
3+
4+
// --- Declarations ---
5+
declaration = { enum_decl | element }
6+
enum_decl = { "enum" ~ ident ~ "=" ~ ident ~ ("|" ~ ident)* }
7+
element = { clafer | constraint }
8+
9+
// --- Clafer Core ---
10+
clafer = {
11+
abstract_mod? ~
12+
gcard? ~
13+
ident ~
14+
super_mod? ~
15+
ref_mod? ~
16+
card? ~
17+
init_mod? ~
18+
elements?
19+
}
20+
21+
constraint = { "[" ~ expr ~ "]" }
22+
elements = { "{" ~ element* ~ "}" }
23+
24+
// --- Modifiers ---
25+
abstract_mod = { "abstract" }
26+
super_mod = { ":" ~ expr }
27+
ref_mod = { "->" ~ expr }
28+
init_mod = { "=" ~ expr }
29+
30+
// --- Cardinalities ---
31+
gcard = { "xor" | "or" | "mux" | "opt" | ncard }
32+
card = { "?" | "+" | "*" | ncard | int }
33+
ncard = { int ~ ".." ~ (int | "*") }
34+
35+
// --- Expressions ---
36+
expr = { iff_expr }
37+
iff_expr = { implies_expr ~ ("<=>" ~ implies_expr)* }
38+
implies_expr = { or_expr ~ ("=>" ~ or_expr)* }
39+
or_expr = { xor_expr ~ ("||" ~ xor_expr)* }
40+
xor_expr = { and_expr ~ ("xor" ~ and_expr)* }
41+
and_expr = { cmp_expr ~ ("&&" ~ cmp_expr)* }
42+
43+
cmp_expr = { add_expr ~ (cmp_op ~ add_expr)* }
44+
cmp_op = { "<=" | ">=" | "<" | ">" | "=" | "!=" | "not in" | "in" }
45+
46+
add_expr = { join_expr ~ (add_op ~ join_expr)* }
47+
add_op = { "+" | "-" }
48+
49+
join_expr = { primary ~ ("." ~ primary)* }
50+
51+
primary = { unary_op* ~ quantifier? ~ (ident | int | str | "(" ~ expr ~ ")") }
52+
unary_op = { "!" | "-" }
53+
quantifier = { "no" | "not" | "lone" | "one" | "some" | "all" }
54+
55+
// --- Tokens ---
56+
ident = @{ ASCII_ALPHA ~ (ASCII_ALPHANUMERIC | "_" | "'")* }
57+
int = @{ ASCII_DIGIT+ }
58+
str = @{ "\"" ~ (!"\"" ~ ANY)* ~ "\"" }
59+
60+
// --- Implicit Whitespace & Comments (Silent) ---
61+
WHITESPACE = _{ " " | "\t" | "\r" | "\n" }
62+
COMMENT = _{
63+
("//" ~ (!"\n" ~ ANY)*) |
64+
("/*" ~ (!"*/" ~ ANY)* ~ "*/")
65+
}

0 commit comments

Comments
 (0)