statebuddy/src/VisualEditor/transition_label.grammar

128 lines
2.2 KiB
Text

start = tlabel / comment
tlabel = _ trigger:trigger _ guard:("[" _ guard _ "]")? _ actions:("/" _ actions )? _ {
return {
kind: "transitionLabel",
trigger,
guard: guard ? guard[2] : {kind: "literal", value: true},
actions: actions ? actions[2] : [],
};
}
trigger = afterTrigger / entryTrigger / exitTrigger / eventTrigger
eventTrigger = event:identifier {
return {kind: "event", event};
}
afterTrigger = "after" _ dur:durationMs {
return {kind: "after", durationMs: dur};
}
entryTrigger = "entry" {
return {kind: "entry"};
}
exitTrigger = "exit" {
return {kind: "exit"};
}
durationMs = num:number _ u:timeUnit {
return num * (u === "s" ? 1000 : 1);
}
timeUnit = "ms" / "s" {
return text();
}
guard = expr
actions = head:action tail:(_ ";" _ action)* _ ";"? {
return [head, ...tail.map(t => t[3])];
}
action = assignment / raise
assignment = lhs:identifier _ "=" _ rhs:expr {
return {kind: "assignment", lhs, rhs};
}
identifier = [a-zA-Z0-9]+ {
return text();
}
number = [0-9]+ {
return parseInt(text());
}
expr = compare
compare = sum:sum rest:((_ ("==" / "!=" / "<" / ">" / "<=" / ">=") _) compare)? {
if (rest === null) {
return sum;
}
return {
kind: "binaryExpr",
operator: rest[0][1],
lhs: sum,
rhs: rest[1],
};
}
sum = prod:product rest:((_ ("+" / "-") _) sum)? {
if (rest === null) {
return prod;
}
return {
kind: "binaryExpr",
operator: rest[0][1],
lhs: prod,
rhs: rest[1],
};
}
product = atom:atom rest:((_ ("*" / "/") _) product)? {
if (rest === null) {
return atom;
}
return {
kind: "binaryExpr",
operator: rest[0][1],
lhs: atom,
rhs: rest[1],
};
}
atom = nested / literal / ref
nested = "(" _ expr:expr _ ")" {
return expr;
}
literal = value:(number / boolean) {
return {kind: "literal", value}
}
ref = variable:identifier {
return {kind: "ref", variable}
}
boolean = ("true" / "false") {
return text() === "true";
}
raise = "^" _ event:identifier {
return {kind: "raise", event};
}
_ "whitespace"
= (comment / [ \t\n\r])*
{ return null; }
comment = "//" _ text:.* _ ('\n' / !.) {
return {
kind: "comment",
text: text.join(''),
};
}