> ## Documentation Index
> Fetch the complete documentation index at: https://docs.myspellchecker.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom Grammar Rules Guide

> Create and customize YAML-based grammar rules for syntactic validation including POS sequences, particles, and register checks.

The built-in grammar rules cover common Myanmar syntactic patterns, but every domain has its own conventions. Formal government documents use different particle patterns than casual chat. You can provide your own YAML rules file to add, override, or disable specific grammar checks without modifying the library.

## Overview

The rule engine checks for:

* Invalid POS sequences (e.g., V-V, P-P patterns)
* Sentence boundary constraints
* Particle chain validation
* Register consistency (formal vs colloquial)
* Negation and classifier rules

## Rule File Location

Default grammar rules are located at:

```python theme={null}
src/myspellchecker/rules/grammar_rules.yaml
```

You can provide custom rules via configuration:

```python theme={null}
from myspellchecker.grammar.config import GrammarRuleConfig

# GrammarRuleConfig loads and manages rules from a YAML file
rule_config = GrammarRuleConfig(config_path="/path/to/custom_rules.yaml")
```

## YAML Schema

### File Structure

```yaml theme={null}
# Grammar rules file structure
version: "1.0.0"
category: "grammar_rules"
description: "Custom grammar validation rules"

metadata:
  created_date: "2025-01-01"
  last_updated: "2025-01-15"
  total_entries: 45
  source: "Custom patterns"

rules:
  # Rule categories
  sentence_start_constraints: [...]
  sentence_end_constraints: [...]
  invalid_sequences: [...]
  required_particles: [...]
  sentence_final_required: [...]
  particle_chains:
    valid_chains: [...]
    invalid_chains: [...]
  register_rules: [...]
  clause_linkage: [...]
  negation_rules: [...]
  classifier_rules: [...]

# Tag definitions
particle_tags:
  "ကို": "P_OBJ"
  "က": "P_SUBJ"
  # ...

interjection_tags:
  "အိုး": "INT"
  # ...
```

## Rule Categories

### Sentence Constraints

Define what particles can or cannot appear at sentence boundaries:

```yaml theme={null}
rules:
  sentence_start_constraints:
    - forbidden_tags: ["P_OBJ", "P_POSS", "P_BEN"]
      forbidden_words: ["ကို", "ရဲ့", "အတွက်"]
      severity: "error"
      message: "Sentence usually cannot start with this particle"
      confidence: 0.90

  sentence_end_constraints:
    - forbidden_tags: ["P_SUBJ", "P_OBJ", "P_COM"]
      forbidden_words: ["က", "ကို", "နှင့်", "နဲ့"]
      severity: "error"
      message: "Sentence cannot end with this particle"
      confidence: 0.90
```

### Invalid POS Sequences

Define patterns that indicate grammatical errors:

```yaml theme={null}
rules:
  invalid_sequences:
    # Consecutive verbs (might need particle)
    - pattern: "V-V"
      severity: "info"
      message: "Consecutive verbs (Serial Verb Construction?)"
      suggestion: "Check if particle is needed if not an SVC"
      confidence: 0.50
      examples:
        incorrect: "သွား စား"
        correct: "သွားပြီး စားတယ်"
        translation: "went and then ate"
      exceptions: ["သွား", "လာ", "နေ", "ပေး", "လိုက်"]

    # Conflicting tense markers
    - pattern: "P_PAST-P_FUT"
      severity: "error"
      message: "Conflicting tense markers (Past + Future)"
      suggestion: "Choose one tense"
      confidence: 0.98
      examples:
        incorrect: "သွားခဲ့မယ်"
        correct: "သွားခဲ့တယ် / သွားမယ်"

    # Number without classifier
    - pattern: "NUM-N"
      severity: "warning"
      message: "Number before Noun without classifier (may be valid in dates, prices, measures)"
      suggestion: "Consider Noun + Number + Classifier pattern"
      confidence: 0.75
      examples:
        incorrect: "တစ် လူ"
        correct: "လူ တစ် ယောက်"
        translation: "one person"
```

### Required Particles

Define when particles are typically required:

```yaml theme={null}
rules:
  required_particles:
    - pattern: "N-V"
      required_one_of: ["က", "ကို", "မှာ", "မှ", "သည်"]
      severity: "warning"
      message: "Noun-verb sequence usually needs case particle"
      confidence: 0.75
      examples:
        questionable: "သူ သွားတယ်"
        better: "သူက သွားတယ်"
        translation: "he went"

  sentence_final_required:
    - pattern: "V$"
      required_one_of: ["တယ်", "ပါတယ်", "သည်", "ပါသည်", "မယ်", "ပြီ"]
      severity: "warning"
      message: "Verb at sentence end usually needs final particle"
      confidence: 0.80
```

### Particle Chains

Define valid and invalid particle combinations:

```yaml theme={null}
rules:
  particle_chains:
    valid_chains:
      - particles: ["က", "တော့"]
        meaning: "Subject + topic/contrast"
        example: "သူကတော့ သွားတယ်"
        translation: "As for him, (he) went"

      - particles: ["ကို", "လည်း"]
        meaning: "Object + also"
        example: "သူ့ကိုလည်း ခေါ်"
        translation: "Call him too"

    invalid_chains:
      - particles: ["က", "ကို"]
        severity: "error"
        message: "Subject marker cannot be followed by object marker"
        confidence: 0.95
        examples:
          incorrect: "သူကကို"
          correct: "သူ့ကို / သူက"

      - particles: ["တယ်", "သည်"]
        severity: "error"
        message: "Mixed colloquial and formal endings"
        confidence: 0.95
```

### Register Rules

Check for consistency between formal and colloquial style:

```yaml theme={null}
rules:
  register_rules:
    formal_endings: ["သည်", "ပါသည်", "မည်", "ပါမည်", "၏"]
    colloquial_endings: ["တယ်", "ပါတယ်", "မယ်", "ပါမယ်", "ဘူး"]
    checks:
      - pattern: "formal_with_colloquial"
        severity: "info"
        message: "Mixed formal and colloquial register in same sentence"
        suggestion: "Consider using consistent register throughout"
        confidence: 0.85
```

### Negation Rules

Validate proper negation patterns:

```yaml theme={null}
rules:
  negation_rules:
    # Standard negation
    - pattern: "မ-V-ဘူး"
      severity: "info"
      message: "Standard negative construction"
      confidence: 0.90
      examples:
        correct: "မသွားဘူး"
        translation: "don't go / won't go"

    # Imperative negation
    - pattern: "မ-V-နဲ့"
      severity: "info"
      message: "Negative imperative (don't)"
      confidence: 0.85
      examples:
        correct: "မသွားနဲ့"
        translation: "don't go!"

    # Missing ဘူး
    - pattern: "မ-V$"
      severity: "warning"
      message: "Negative verb may need ဘူး ending"
      suggestion: "Add ဘူး for complete negation"
      confidence: 0.70
```

### Classifier Rules

Validate numeral-classifier-noun patterns:

```yaml theme={null}
rules:
  classifier_rules:
    - pattern: "N-NUM-CLF"
      severity: "info"
      message: "Standard classifier construction"
      confidence: 0.80
      examples:
        correct: "လူ သုံးယောက်"
        translation: "three people"

    - pattern: "CLF-NUM"
      severity: "error"
      message: "Classifier before numeral (wrong order)"
      suggestion: "Classifier should follow numeral"
      confidence: 0.95
```

## Tag Definitions

### Particle Tags

Map specific words to POS tags for validation:

```yaml theme={null}
particle_tags:
  # Possessive
  "ရဲ့": "P_POSS"
  "၏": "P_POSS"

  # Object markers
  "ကို": "P_OBJ"
  "အား": "P_OBJ"

  # Subject marker
  "က": "P_SUBJ"

  # Location markers
  "မှာ": "P_LOC"
  "၌": "P_LOC"
  "တွင်": "P_LOC"

  # Sentence endings (colloquial)
  "တယ်": "P_SENT"
  "ပါတယ်": "P_SENT"
  "မယ်": "P_SENT"
  "ဘူး": "P_NEG_SENT"

  # Sentence endings (formal)
  "သည်": "P_SENT"
  "ပါသည်": "P_SENT"
  "မည်": "P_SENT"
```

### Interjection Tags

```yaml theme={null}
interjection_tags:
  "အိုး": "INT"      # Oh! (surprise)
  "ဟေ့": "INT"       # Hey! (attention)
  "အော်": "INT"      # Ah! (exclamation)
  "ကွာ": "INT"       # Emphatic particle
  "ဟုတ်လား": "INT"   # Really?
```

## Severity Levels

| Level     | Description                       | Action                        |
| --------- | --------------------------------- | ----------------------------- |
| `error`   | Clear grammatical error           | Flag as error, suggest fix    |
| `warning` | Likely error, context-dependent   | Flag with medium confidence   |
| `info`    | Informational, may be intentional | Optional flag, low confidence |

## Confidence Scores

Confidence ranges from 0.0 to 1.0:

| Range      | Meaning                              |
| ---------- | ------------------------------------ |
| 0.90-1.0   | Very high confidence, clear error    |
| 0.70-0.89  | High confidence, likely error        |
| 0.50-0.69  | Medium confidence, context-dependent |
| Under 0.50 | Low confidence, informational        |

## Creating Custom Rules

<Steps>
  <Step title="Create YAML File">
    ```yaml theme={null}
    # my_custom_rules.yaml
    version: "1.0.0"
    category: "custom_grammar_rules"
    description: "Domain-specific grammar rules"

    rules:
      invalid_sequences:
        - pattern: "ADJ-ADJ"
          severity: "warning"
          message: "Multiple consecutive adjectives"
          confidence: 0.60
    ```
  </Step>

  <Step title="Load Custom Rules">
    ```python theme={null}
    from myspellchecker import SpellChecker
    from myspellchecker.core.config import GrammarEngineConfig, SpellCheckerConfig
    from myspellchecker.core.builder import SpellCheckerBuilder

    # Enable grammar checking via SpellCheckerConfig
    config = SpellCheckerConfig(
        use_rule_based_validation=True,
    )
    checker = SpellCheckerBuilder().with_config(config).build()

    # To customize confidence thresholds, pass GrammarEngineConfig
    # directly to SyntacticRuleChecker:
    #   from myspellchecker.grammar import SyntacticRuleChecker
    #   engine = SyntacticRuleChecker(
    #       grammar_config=GrammarEngineConfig(
    #           default_confidence_threshold=0.80,
    #           high_confidence=0.90,
    #       )
    #   )
    ```
  </Step>

  <Step title="Test Rules">
    ```python theme={null}
    result = checker.check("သူကကို ခေါ်တယ်")

    for error in result.errors:
        if error.error_type == "grammar_error":
            print(f"Grammar: {error.text} - {error.suggestions}")
    ```
  </Step>
</Steps>

## Best Practices

### 1. Use Examples

Always include examples in rules:

```yaml theme={null}
examples:
  incorrect: "သွားခဲ့မယ်"
  correct: "သွားခဲ့တယ် / သွားမယ်"
  translation: "went / will go"
```

### 2. Include Exceptions

List valid exceptions to patterns:

```yaml theme={null}
exceptions: ["သွား", "လာ", "နေ", "ပေး"]  # Serial verb auxiliaries
```

### 3. Set Appropriate Confidence

* High confidence (0.9+) for clear errors
* Medium confidence (0.6-0.8) for likely errors
* Low confidence (\<0.5) for informational patterns

### 4. Group Related Rules

Organize rules by category for maintainability:

```yaml theme={null}
rules:
  tense_rules:
    - pattern: "P_PAST-P_FUT" ...
    - pattern: "P_PAST-P_PAST" ...

  case_rules:
    - pattern: "P_SUBJ-P_OBJ" ...
```

## Debugging Rules

### Enable Grammar Debug Logging

```python theme={null}
from myspellchecker.utils.logging_utils import configure_logging

configure_logging(level="DEBUG")
```

### Check Rule Matching

```python theme={null}
from myspellchecker.grammar.engine import SyntacticRuleChecker
from myspellchecker.providers import SQLiteProvider

# SyntacticRuleChecker requires a DictionaryProvider as first argument
provider = SQLiteProvider(database_path="/path/to/dict.db")
grammar_checker = SyntacticRuleChecker(provider)

# check_sequence() only takes words; POS tags are looked up internally
errors = grammar_checker.check_sequence(
    words=["သူ", "က", "ကို", "ခေါ်", "တယ်"]
)

for idx, error_word, suggestion in errors:
    print(f"Position: {idx}")
    print(f"Error word: {error_word}")
    print(f"Suggestion: {suggestion}")
```

## See Also

* [Grammar Checking](/features/grammar-checking) - Feature overview
* [POS Tagging](/features/pos-tagging) - Part-of-speech tagging
* [Viterbi Algorithm](/algorithms/viterbi) - POS tagger implementation
* [Error Types](/reference/error-types) - Error type reference
