Parser for CSP-CASL processes.
csp_casl_process :: AParser st PROCESS
csp_casl_process = do p <- process
recProcess :: AParser st REC_PROCESS
recProcess = do asKey letS
rds <- recProcessDefn `sepBy` semiT
return (RecProcessConstructor rds p)
-- Recursive process definitions
recProcessDefn :: AParser st REC_PROCESS_DEFN
recProcessDefn = try (do pn <- process_name
return (RecProcessVar pn v es p)
<|> (do pn <- process_name
return (RecProcessSimple pn p)
varEventSet :: AParser st (VAR, EVENT_SET)
varEventSet = do v <- var
process_name :: AParser st PROCESS_NAME
process_name = do p_name <- parseId csp_casl_keywords
-- PROCESS => PARALLEL_PROCESS
process :: AParser st PROCESS
process = conditional_process <|> parallel_process
conditional_process :: AParser st PROCESS
conditional_process = do try (asKey ifS)
return (ConditionalProcess f p q)
-- PARALLEL_PROCESS => CHOICE_PROCESS
-- | PARALLEL_PROCESS || CHOICE_PROCESS
-- | PARALLEL_PROCESS ||| CHOICE_PROCESS
parallel_process :: AParser st PROCESS
parallel_process = complex_parallel `chainl1` parallel_operator
parallel_operator :: AParser st (PROCESS -> PROCESS -> PROCESS)
parallel_operator = try (do asKey interleavingS
try (do asKey synchronousS
synchronous :: PROCESS -> PROCESS -> PROCESS
synchronous left right = SynchronousParallel left right
interleaving :: PROCESS -> PROCESS -> PROCESS
interleaving left right = Interleaving left right
complex_parallel :: AParser st PROCESS
complex_parallel = try (do p <- choice_process
asKey general_parallel_openS
asKey general_parallel_closeS
return (GeneralisedParallel p es q)
try (do p <- choice_process
asKey alpha_parallel_openS
asKey alpha_parallel_sepS
asKey alpha_parallel_closeS
return (AlphabetisedParallel p es_p es_q q)
-- CHOICE_PROCESS => PREFIX_SEQUENCE_PROCESS
-- | CHOICE_PROCESS [] PREFIX_SEQUENCE_PROCESS
-- | CHOICE_PROCESS |~| PREFIX_SEQUENCE_PROCESS
choice_process :: AParser st PROCESS
choice_process = sequence_process `chainl1` choice_operator
choice_operator :: AParser st (PROCESS -> PROCESS -> PROCESS)
choice_operator = try (do asKey external_choiceS
try (do asKey internal_choiceS
external :: PROCESS -> PROCESS -> PROCESS
external left right = ExternalChoice left right
internal :: PROCESS -> PROCESS -> PROCESS
internal left right = InternalChoice left right
-- SEQUENCE_PROCESS => PREFIX_PROCESS
-- | SEQUENCE_PROCESS ; PREFIX_PROCESS
sequence_process :: AParser st PROCESS
sequence_process = prefix_process `chainl1` sequence_operator
sequence_operator :: AParser st (PROCESS -> PROCESS -> PROCESS)
sequence_operator = try (do asKey semicolonS
sequencing :: PROCESS -> PROCESS -> PROCESS
sequencing left right = Sequential left right
-- PREFIX_PROCESS => [] VAR: EVENT-SET -> HIDING_RENAMING_PROCESS
-- | EVENT -> HIDING_RENAMING_PROCESS
-- | HIDING_RENAMING_PROCESS
prefix_process :: AParser st PROCESS
prefix_process = try (do asKey external_prefixS
return (ExternalPrefixProcess v es p)
try (do asKey internal_prefixS
return (InternalPrefixProcess v es p)
return (PrefixProcess e p)
-- HIDING_RENAMING_PROCESS => PRIMTIVE_PROCESS HIDING_RENAMING_W
-- HIDING_RENAMING_W => \ EVENT-SET
hiding_renaming_process :: AParser st PROCESS
hiding_renaming_process = do pl <- parenthesised_or_primitive_process
p <- (hiding_renaming_w pl)
hiding_renaming_w :: PROCESS -> AParser st PROCESS
hiding_renaming_w pl = try (do asKey hidingS
p <- (hiding_renaming_w (Hiding pl es))
try (do asKey renaming_openS
p <- (hiding_renaming_w (Renaming pl rn))
-- PARENTHESISED_OR_PRIMITIVE_PROCESS => (PROCESS)
parenthesised_or_primitive_process :: AParser st PROCESS
parenthesised_or_primitive_process = do asKey parens_openS
primitive_process :: AParser st PROCESS
primitive_process = try run <|> try chaos <|> try divergence <|> try skip <|> stop
-- Hard-coded primitive processes.
run :: AParser st PROCESS
chaos :: AParser st PROCESS
-- Can't just call this "div" because that clashes with div from the
divergence :: AParser st PROCESS
divergence = do asKey divS
skip :: AParser st PROCESS
stop :: AParser st PROCESS
-- Event sets are just CASL sorts...
event_set :: AParser st EVENT_SET
event_set = do sort_id <- sortId csp_casl_keywords
return (EventSet sort_id)
-- Events are CASL terms, but will (later) include stuff to with
event :: AParser st EVENT
-- Formulas are CASL formulas. We make our own wrapper around them
formula :: AParser st CSP_FORMULA
-- Primitive renaming is done using an operator name or a predicate
-- name. They're both Ids. Separation between operator or predicate
-- (or some other non-applicable Id) must be a static analysis
primitive_renaming :: AParser st PRIMITIVE_RENAMING
primitive_renaming = do { rid <- parseId csp_casl_keywords
var = varId csp_casl_keywords