diff options
| author | 2025-09-13 02:34:14 +0800 | |
|---|---|---|
| committer | 2025-09-13 02:34:14 +0800 | |
| commit | 00670619f3a9ac80683f1a1d751349e010c602dc (patch) | |
| tree | 242ccdbede9b38099ed773ea5ab725ded053843f /src/parser.rs | |
| parent | 93d462c41cf0ed359475f07578bac511a329c580 (diff) | |
| download | OneRoll-00670619f3a9ac80683f1a1d751349e010c602dc.tar.gz OneRoll-00670619f3a9ac80683f1a1d751349e010c602dc.zip | |
feat: introduce new dice modifiers for grouping and merging, enhance variable references and instruction sequences in parser
Diffstat (limited to 'src/parser.rs')
| -rw-r--r-- | src/parser.rs | 59 |
1 files changed, 56 insertions, 3 deletions
diff --git a/src/parser.rs b/src/parser.rs index 20cd992..73b5c49 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -16,15 +16,38 @@ impl DiceParser { .map_err(|e| DiceError::ParseError(e.to_string()))?; let pair = pairs.peek().unwrap(); - Self::parse_dice_expr(pair) + Self::parse_instruction_list(pair) } fn parse_dice_expr(pair: pest::iterators::Pair<Rule>) -> Result<Expression, DiceError> { match pair.as_rule() { Rule::main => { - // main 规则包含 dice_expr let inner = pair.into_inner().next().unwrap(); - Self::parse_dice_expr(inner) + Self::parse_instruction_list(inner) + } + Rule::instruction_list => Self::parse_instruction_list(pair), + Rule::instruction => { + let inner = pair.into_inner().next().unwrap(); + match inner.as_rule() { + Rule::var_ref => { + let mut pairs = inner.into_inner(); + let n = pairs.next().unwrap().as_str().trim_start_matches('$').parse::<i32>() + .map_err(|_| DiceError::ParseError("无效的变量引用".to_string()))?; + if n <= 0 { return Err(DiceError::ParseError("变量引用必须>=1".to_string())); } + + let mut modifiers = Vec::new(); + if let Some(modifiers_pair) = pairs.next() { + for modifier_pair in modifiers_pair.into_inner() { + let modifier = Self::parse_modifier(modifier_pair)?; + modifiers.push(modifier); + } + } + + // Store variable reference with modifiers for special handling + Ok(Expression::VariableRefWithModifiers(n as usize, modifiers)) + } + _ => Self::parse_dice_expr(inner), + } } Rule::dice_expr => { let mut pairs = pair.into_inner(); @@ -168,6 +191,16 @@ impl DiceParser { .map_err(|_| DiceError::ParseError("无效的计数数值".to_string()))?; Ok(DiceModifier::Count(num)) } + Rule::merge => Ok(DiceModifier::Merge), + Rule::group => { + let s = inner.as_str(); + let show_structure = s.starts_with("gs"); + let inn = inner.into_inner(); + // last number + let num = inn.last().unwrap().as_str().parse::<i32>() + .map_err(|_| DiceError::ParseError("无效的分组阈值".to_string()))?; + Ok(DiceModifier::Group { threshold: num, show_structure }) + } _ => Err(DiceError::ParseError("未知的修饰符".to_string())), } } @@ -175,6 +208,26 @@ impl DiceParser { } } + fn parse_instruction_list(pair: pest::iterators::Pair<Rule>) -> Result<Expression, DiceError> { + match pair.as_rule() { + Rule::instruction_list => { + let mut exprs = Vec::new(); + for p in pair.into_inner() { + if p.as_rule() == Rule::instruction { + let e = Self::parse_dice_expr(p)?; + exprs.push(e); + } + } + if exprs.len() == 1 { + Ok(exprs.into_iter().next().unwrap()) + } else { + Ok(Expression::Sequence(exprs)) + } + } + _ => Self::parse_dice_expr(pair), + } + } + fn parse_comment(pair: pest::iterators::Pair<Rule>) -> Result<Option<String>, DiceError> { match pair.as_rule() { Rule::comment => { |
