gram
Safe HaskellSafe-Inferred
LanguageHaskell2010

Gram

Description

Main module for the Gram library.

This module provides convenient access to all Gram library functionality by re-exporting public APIs from core modules. Import this module to access all Gram types, functions, and utilities without needing to import individual modules.

Library Organization

The Gram library is organized into several modules:

  • Gram.Serialize - Serialization of Pattern Subject to gram notation
  • Gram.Parse - Parsing gram notation to Pattern Subject
  • Gram.Validate - Validation of parsed Gram AST for semantic correctness

Usage

Import the main Gram module to access all functionality:

>>> import Gram
>>> import Pattern.Core (Pattern(..))
>>> import Subject.Core (Subject(..), Symbol(..))
>>> import Data.Set (Set)
>>> import qualified Data.Set as Set
>>> let s = Subject (Symbol "n") (Set.fromList ["Person"]) empty
>>> let p = Pattern { value = s, elements = [] }
>>> toGram p
"(n:Person)"

All public functions and types from Gram.Serialize, Gram.Parse, and Gram.Validate are available through this module. See individual module documentation for detailed information about specific functionality.

Root record and first-pattern

fromGram and toGram preserve a leading bare record as the first pattern (anonymous identity, no labels, no elements). fromGramWithHeader and toGramWithHeader keep the header as Maybe PropertyRecord / PropertyRecord separate from the pattern list.

Re-export Structure

This module re-exports:

  • All public exports from Gram.Serialize (toGram, etc.)
  • All public exports from Gram.Parse (fromGram, ParseError, etc.)
  • All public exports from Gram.Validate (validate, ValidationError, etc.)

Internal implementation details and helper functions are not exported through this module, ensuring a clean public API.

Synopsis

Parsing

fromGram :: String -> Either ParseError [Pattern Subject] Source #

Parse gram notation into a list of Pattern Subject.

A leading bare record is represented as an anonymous, no-elements pattern (Pattern (Subject (Symbol "") Set.empty props) []) and placed first in the list. Empty or whitespace-only input yields Right [].

This function preserves anonymous subjects as 'Symbol ""' for round-trip compatibility. Use fromGramWithIds to assign generated IDs.

fromGramWithIds :: String -> Either ParseError [Pattern Subject] Source #

Parse gram notation string into a list of Pattern Subjects with ID assignment.

This function is equivalent to applying assignIdentities to each pattern in the result of fromGram. It assigns unique sequential IDs (e.g., #1, #2) to all anonymous subjects in the parsed patterns.

Use this function when you need unique identifiers for anonymous subjects, such as for graph algorithms or when distinguishing between anonymous instances is important.

For round-trip compatibility, use fromGram instead, which preserves anonymity.

fromGramWithHeader :: String -> Either ParseError (Maybe (Map String Value), [Pattern Subject]) Source #

Parse gram notation into an optional header and a list of patterns.

Returns (Maybe PropertyRecord, [Pattern Subject]). The leading bare record, if present, is only in the Maybe; it is not in the pattern list. Empty or whitespace-only input yields Right (Nothing, []).

data ParseError Source #

Parse error type for gram notation parsing.

Constructors

ParseError String 

Instances

Instances details
Show ParseError Source # 
Instance details

Defined in Gram.Parse

Eq ParseError Source # 
Instance details

Defined in Gram.Parse

Serialization

toGram :: [Pattern Subject] -> String Source #

Serialize a list of Patterns to gram notation (newline-separated).

First-pattern rule: If the first pattern is anonymous (identity == Symbol ""), has no labels, and has no elements, it is serialized as a bare root record {k:v} or {}. Only the first pattern is considered; the same shape in any other position is serialized with serializePattern.

Round-trip: fromGram s >>= toGram preserves a leading bare record as the first element. With fromGramWithIds, the header pattern gets an assigned identity and is no longer header-like, so it will serialize as a normal pattern (e.g. (#1 {...})).

toGramWithHeader :: Map String Value -> [Pattern Subject] -> String Source #

Serialize a header record and a list of Patterns to gram notation.

The header is always emitted as a bare record {k:v} or {}, then a newline, then toGram of the patterns. The header is explicit; the first-pattern rule of toGram still applies to the pattern list (so a header-like first pattern would also serialize as a bare record on the next line).

serializePattern :: Pattern Subject -> String Source #

Serialize a Pattern Subject to gram notation.

Converts a Pattern Subject data structure into its gram notation string representation. The output follows the gram notation specification: - Patterns with elements use subject syntax: `[attributes | elements]` - Patterns without elements use node syntax: (attributes)

Examples

Simple node (no elements):

>>> import Pattern.Core (Pattern(..))
>>> import Subject.Core (Subject(..), Symbol(..))
>>> import Data.Set (Set)
>>> import qualified Data.Set as Set
>>> let s = Subject (Symbol "n") (Set.fromList ["Person"]) empty
>>> let p = Pattern { value = s, elements = [] }
>>> serializePattern p
"(n:Person)"

Node with properties (no elements):

>>> import Data.Map (fromList)
>>> import Subject.Value (VString)
>>> let s = Subject (Symbol "n") (Set.fromList ["Person"]) (fromList [("name", VString "Alice")])
>>> let p = Pattern { value = s, elements = [] }
>>> serializePattern p
"(n:Person {name:\"Alice\"})"

Subject with nested elements:

>>> let inner1 = Pattern (Subject (Symbol "a") Set.empty empty) []
>>> let inner2 = Pattern (Subject (Symbol "b") Set.empty empty) []
>>> let outer = Pattern (Subject (Symbol "g") Set.empty empty) [inner1, inner2]
>>> serializePattern outer
"[g | a, b]"

Validation

validate :: GramDoc -> Either [ValidationError] () Source #

Validate a parsed Gram AST.