1
1
mirror of https://github.com/github/semantic.git synced 2024-12-24 23:42:31 +03:00

Merge remote-tracking branch 'origin/master' into typescript-assignment

This commit is contained in:
joshvera 2017-09-19 17:04:27 -04:00
commit d0fb557bec
17 changed files with 198 additions and 188 deletions

View File

@ -138,24 +138,6 @@ executable semantic
default-language: Haskell2010
default-extensions: FlexibleInstances, OverloadedStrings, RecordWildCards
executable slurp
hs-source-dirs: app
main-is: Slurp.hs
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends: base
, aeson
, base64-bytestring
, bytestring
, filepath
, github
, netrc
, regex-compat
, text
, text-conversions
, vector
default-language: Haskell2010
default-extensions: FlexibleInstances, OverloadedStrings, RecordWildCards
test-suite test
type: exitcode-stdio-1.0
hs-source-dirs: test

View File

@ -32,9 +32,6 @@ instance GAlign Identity where
instance Apply GAlign fs => GAlign (Union fs) where
galignWith f = (join .) . apply2' (Proxy :: Proxy GAlign) (\ inj -> (fmap inj .) . galignWith f)
instance GAlign (Union '[]) where
galignWith _ _ _ = Nothing
instance GAlign NonEmpty where
galignWith f (a:|as) (b:|bs) = Just (f (These a b) :| alignWith f as bs)

View File

@ -4,16 +4,20 @@ module Interpreter
, decoratingWith
, diffTermsWith
, comparableByConstructor
, equivalentTerms
) where
import Algorithm
import Control.Monad.Free.Freer
import Data.Align.Generic
import Data.Functor.Classes (Eq1)
import Data.Functor.Classes (Eq1(..))
import Data.Hashable (Hashable)
import Data.Maybe (isJust)
import Data.Record
import Data.Text (Text)
import Data.These
import Data.Union
import qualified Data.Syntax.Declaration as Declaration
import Diff
import Info hiding (Return)
import RWS
@ -26,7 +30,7 @@ diffTerms :: (HasField fields1 Category, HasField fields2 Category)
=> Term Syntax (Record fields1) -- ^ A term representing the old state.
-> Term Syntax (Record fields2) -- ^ A term representing the new state.
-> Diff Syntax (Record fields1) (Record fields2)
diffTerms = decoratingWith getLabel getLabel (diffTermsWith algorithmWithTerms comparableByCategory)
diffTerms = decoratingWith getLabel getLabel (diffTermsWith algorithmWithTerms comparableByCategory (equalTerms comparableByCategory))
-- | Diff two terms by decorating with feature vectors computed using the supplied labelling algebra, and stripping the feature vectors from the resulting diff.
decoratingWith :: (Hashable label, Traversable syntax)
@ -43,17 +47,18 @@ diffTermsWith :: forall syntax fields1 fields2
. (Eq1 syntax, GAlign syntax, Traversable syntax)
=> (Term syntax (Record (FeatureVector ': fields1)) -> Term syntax (Record (FeatureVector ': fields2)) -> Algorithm (Term syntax) (Diff syntax (Record (FeatureVector ': fields1)) (Record (FeatureVector ': fields2))) (Diff syntax (Record (FeatureVector ': fields1)) (Record (FeatureVector ': fields2)))) -- ^ A function producing syntax-directed continuations of the algorithm.
-> ComparabilityRelation syntax (Record (FeatureVector ': fields1)) (Record (FeatureVector ': fields2)) -- ^ A relation on terms used to determine comparability and equality.
-> (Term syntax (Record (FeatureVector ': fields1)) -> Term syntax (Record (FeatureVector ': fields2)) -> Bool) -- ^ A relation used to determine term equivalence.
-> Term syntax (Record (FeatureVector ': fields1)) -- ^ A term representing the old state.
-> Term syntax (Record (FeatureVector ': fields2)) -- ^ A term representing the new state.
-> Diff syntax (Record (FeatureVector ': fields1)) (Record (FeatureVector ': fields2)) -- ^ The resulting diff.
diffTermsWith refine comparable t1 t2 = runFreer decompose (diff t1 t2)
diffTermsWith refine comparable eqTerms t1 t2 = runFreer decompose (diff t1 t2)
where decompose :: AlgorithmF (Term syntax) (Diff syntax (Record (FeatureVector ': fields1)) (Record (FeatureVector ': fields2))) result -> Algorithm (Term syntax) (Diff syntax (Record (FeatureVector ': fields1)) (Record (FeatureVector ': fields2))) result
decompose step = case step of
Algorithm.Diff t1 t2 -> refine t1 t2
Linear t1 t2 -> case galignWith diffThese (unwrap t1) (unwrap t2) of
Just result -> merge (extract t1, extract t2) <$> sequenceA result
_ -> byReplacing t1 t2
RWS as bs -> traverse diffThese (rws comparable as bs)
RWS as bs -> traverse diffThese (rws comparable eqTerms as bs)
Delete a -> pure (deleting a)
Insert b -> pure (inserting b)
Replace a b -> pure (replacing a b)
@ -116,3 +121,20 @@ comparableByCategory (In a _) (In b _) = category a == category b
-- | Test whether two terms are comparable by their constructor.
comparableByConstructor :: GAlign syntax => ComparabilityRelation syntax ann1 ann2
comparableByConstructor (In _ a) (In _ b) = isJust (galign a b)
-- | Equivalency relation for terms. Equivalence is determined by functions and
-- methods with equal identifiers/names and recursively by equivalent terms with
-- identical shapes.
equivalentTerms :: (Declaration.Method :< fs, Declaration.Function :< fs, Apply Functor fs, Apply Foldable fs, Apply GAlign fs, Apply Eq1 fs)
=> Term (Union fs) a
-> Term (Union fs) b
-> Bool
equivalentTerms a b | Just (Declaration.Method _ _ identifierA _ _) <- prj (unwrap a)
, Just (Declaration.Method _ _ identifierB _ _) <- prj (unwrap b)
= liftEq equivalentTerms (unwrap identifierA) (unwrap identifierB)
| Just (Declaration.Function _ identifierA _ _) <- prj (unwrap a)
, Just (Declaration.Function _ identifierB _ _) <- prj (unwrap b)
= liftEq equivalentTerms (unwrap identifierA) (unwrap identifierB)
| Just aligned <- galignWith (these (const False) (const False) equivalentTerms) (unwrap a) (unwrap b)
= and aligned
| otherwise = False

View File

@ -10,6 +10,7 @@ import Data.Syntax (makeTerm, parseError)
import qualified Data.Syntax as Syntax
import Data.Syntax.Assignment hiding (Assignment, Error)
import qualified Data.Syntax.Assignment as Assignment
import qualified Data.Syntax.Declaration as Declaration
import qualified Data.Syntax.Literal as Literal
import Language.JSON.Grammar as Grammar
import qualified Term
@ -26,6 +27,9 @@ type Syntax =
, Literal.Null
, Literal.String
, Literal.TextElement
-- NB: Diffing requires Methods and Functions in the union.
, Declaration.Method
, Declaration.Function
, Syntax.Error
, []
]

View File

@ -1,4 +1,4 @@
{-# LANGUAGE DataKinds, DeriveAnyClass, GADTs, RankNTypes, TypeOperators #-}
{-# LANGUAGE DataKinds, GADTs, RankNTypes, TypeOperators #-}
module Language.Markdown.Syntax
( assignment
, Syntax
@ -14,6 +14,7 @@ import Data.Syntax (makeTerm)
import qualified Data.Syntax as Syntax
import Data.Syntax.Assignment hiding (Assignment, Error)
import qualified Data.Syntax.Assignment as Assignment
import qualified Data.Syntax.Declaration as Declaration
import qualified Data.Syntax.Markup as Markup
import qualified Data.Text as Text
import Data.Text.Encoding (encodeUtf8)
@ -45,6 +46,9 @@ type Syntax =
, Markup.Strong
, Markup.Text
, Markup.Strikethrough
-- NB: Diffing requires Methods and Functions in the union.
, Declaration.Method
, Declaration.Function
-- Assignment errors; cmark does not provide parse errors.
, Syntax.Error
, []

View File

@ -5,6 +5,8 @@ import Language.Haskell.TH
import TreeSitter.Language
import TreeSitter.Python
-- Regenerate template haskell code when these files change:
addDependentFileRelative "../../../vendor/haskell-tree-sitter/languages/python/vendor/tree-sitter-python/src/parser.c"
-- | Statically-known rules corresponding to symbols in the grammar.
-- v4 - bump this to regenerate
mkSymbolDatatype (mkName "Grammar") tree_sitter_python

View File

@ -37,6 +37,8 @@ type Syntax =
, Declaration.Decorator
, Declaration.Function
, Declaration.Import
-- NB: Diffing requires Methods in the union.
, Declaration.Method
, Declaration.Variable
, Expression.Arithmetic
, Expression.Boolean

View File

@ -795,7 +795,7 @@ expressions :: Assignment
expressions = makeTerm <$> location <*> many expression
identifier :: Assignment
identifier = (makeTerm <$> symbol Identifier <*> (Syntax.Identifier <$> source)) <|> (makeTerm <$> symbol Identifier' <*> (Syntax.Identifier <$> source))
identifier = (makeTerm <$> symbol Identifier' <*> (Syntax.Identifier <$> source)) <|> (makeTerm <$> symbol Identifier <*> (Syntax.Identifier <$> source))
literal :: Assignment
literal =

View File

@ -8,6 +8,7 @@ module RWS
, pqGramDecorator
, Gram(..)
, defaultD
, equalTerms
) where
import Control.Applicative (empty)
@ -57,14 +58,15 @@ data TermOrIndexOrNone term = Term term | Index {-# UNPACK #-} !Int | None
rws :: (Eq1 syntax, Foldable syntax, Functor syntax, GAlign syntax)
=> ComparabilityRelation syntax (Record (FeatureVector ': fields1)) (Record (FeatureVector ': fields2))
-> (Term syntax (Record (FeatureVector ': fields1)) -> Term syntax (Record (FeatureVector ': fields2)) -> Bool)
-> [Term syntax (Record (FeatureVector ': fields1))]
-> [Term syntax (Record (FeatureVector ': fields2))]
-> RWSEditScript syntax (Record (FeatureVector ': fields1)) (Record (FeatureVector ': fields2))
rws _ as [] = This <$> as
rws _ [] bs = That <$> bs
rws canCompare [a] [b] = if canCompareTerms canCompare a b then [These a b] else [That b, This a]
rws canCompare as bs =
let sesDiffs = ses (equalTerms canCompare) as bs
rws _ _ as [] = This <$> as
rws _ _ [] bs = That <$> bs
rws canCompare _ [a] [b] = if canCompareTerms canCompare a b then [These a b] else [That b, This a]
rws canCompare equivalent as bs =
let sesDiffs = ses equivalent as bs
(featureAs, featureBs, mappedDiffs, allDiffs) = genFeaturizedTermsAndDiffs sesDiffs
(diffs, remaining) = findNearestNeighboursToDiff canCompare allDiffs featureAs featureBs
diffs' = deleteRemaining diffs remaining

View File

@ -1,4 +1,4 @@
{-# LANGUAGE DeriveAnyClass, MultiParamTypeClasses, RankNTypes, TypeOperators #-}
{-# LANGUAGE MultiParamTypeClasses, RankNTypes, TypeOperators, ScopedTypeVariables #-}
module Renderer.TOC
( renderToCDiff
, renderToCTerm
@ -29,6 +29,7 @@ import Data.Functor.Both hiding (fst, snd)
import Data.Functor.Foldable (cata)
import Data.Function (on)
import Data.List.NonEmpty (nonEmpty)
import Data.List (sortOn)
import Data.Maybe (fromMaybe, mapMaybe)
import Data.Output
import Data.Record
@ -112,7 +113,7 @@ syntaxDeclarationAlgebra Blob{..} (In a r) = case r of
where getSource = toText . flip Source.slice blobSource . byteRange . extract
-- | Compute 'Declaration's for methods and functions.
declarationAlgebra :: (Declaration.Function :< fs, Declaration.Method :< fs, Syntax.Error :< fs, Syntax.Empty :< fs, Apply Functor fs, HasField fields Range, HasField fields Span)
declarationAlgebra :: (Declaration.Function :< fs, Declaration.Method :< fs, Syntax.Empty :< fs, Syntax.Error :< fs, Apply Functor fs, HasField fields Range, HasField fields Span)
=> Blob
-> RAlgebra (TermF (Union fs) (Record fields)) (Term (Union fs) (Record fields)) (Maybe Declaration)
declarationAlgebra Blob{..} (In a r)
@ -137,6 +138,7 @@ declarationAlgebra Blob{..} (In a r)
| Just err@Syntax.Error{} <- prj r
= Just $ ErrorDeclaration (T.pack (formatTOCError (Syntax.unError (sourceSpan a) err))) blobLanguage
| otherwise = Nothing
where getSource = toText . flip Source.slice blobSource . byteRange
-- | Compute 'Declaration's with the headings of 'Markup.Section's.
@ -185,18 +187,32 @@ termTableOfContentsBy selector = cata termAlgebra
where termAlgebra r | Just a <- selector r = [a]
| otherwise = fold r
dedupe :: HasField fields (Maybe Declaration) => [Entry (Record fields)] -> [Entry (Record fields)]
dedupe = foldl' go []
where go xs x | (_, _:_) <- find (exactMatch `on` entryPayload) x xs = xs
| (front, similar : back) <- find (similarMatch `on` entryPayload) x xs =
front <> (Replaced (entryPayload similar) : back)
| otherwise = xs <> [x]
newtype DedupeKey = DedupeKey (Maybe T.Text, Maybe T.Text) deriving (Eq, Ord)
find p x = List.break (p x)
exactMatch = (==) `on` getDeclaration
similarMatch a b = sameCategory a b && similarDeclaration a b
sameCategory = (==) `on` fmap toCategoryName . getDeclaration
similarDeclaration = (==) `on` fmap (toLower . declarationIdentifier) . getDeclaration
-- Dedupe entries in a final pass. This catches two specific scenarios with
-- different behaviors:
-- 1. Identical entries are in the list.
-- Action: take the first one, drop all subsequent.
-- 2. Two similar entries (defined by a case insensitive comparision of their
-- identifiers) are in the list.
-- Action: Combine them into a single Replaced entry.
dedupe :: forall fields. HasField fields (Maybe Declaration) => [Entry (Record fields)] -> [Entry (Record fields)]
dedupe = let tuples = sortOn fst . Map.elems . snd . foldl' go (0, Map.empty) in (fmap . fmap) snd tuples
where
go :: HasField fields (Maybe Declaration)
=> (Int, Map.Map DedupeKey (Int, Entry (Record fields)))
-> Entry (Record fields)
-> (Int, Map.Map DedupeKey (Int, Entry (Record fields)))
go (index, m) x | Just (_, similar) <- Map.lookup (dedupeKey x) m
= if exactMatch similar x
then (succ index, m)
else
let replacement = Replaced (entryPayload similar)
in (succ index, Map.insert (dedupeKey replacement) (index, replacement) m)
| otherwise = (succ index, Map.insert (dedupeKey x) (index, x) m)
dedupeKey entry = DedupeKey ((fmap toCategoryName . getDeclaration . entryPayload) entry, (fmap (toLower . declarationIdentifier) . getDeclaration . entryPayload) entry)
exactMatch = (==) `on` (getDeclaration . entryPayload)
-- | Construct a 'JSONSummary' from an 'Entry'. Returns 'Nothing' for 'Unchanged' patches.
entrySummary :: (HasField fields (Maybe Declaration), HasField fields Span) => Entry (Record fields) -> Maybe JSONSummary

View File

@ -46,7 +46,7 @@ parseBlobs renderer = fmap toOutput . distributeFoldMap (parseBlob renderer) . f
parseBlob :: TermRenderer output -> Blob -> Task output
parseBlob renderer blob@Blob{..} = case (renderer, blobLanguage) of
(ToCTermRenderer, Just Language.Markdown) -> parse markdownParser blob >>= decorate (markupSectionAlgebra blob) >>= render (renderToCTerm blob)
(ToCTermRenderer, Just Language.Python) -> parse pythonParser blob >>= decorate (declarationAlgebra blob) . hoistTerm (weaken :: Union fs a -> Union (Declaration.Method ': fs) a) >>= render (renderToCTerm blob)
(ToCTermRenderer, Just Language.Python) -> parse pythonParser blob >>= decorate (declarationAlgebra blob) >>= render (renderToCTerm blob)
(ToCTermRenderer, Just Language.TypeScript) -> parse typescriptParser blob >>= decorate (declarationAlgebra blob) >>= render (renderToCTerm blob)
(ToCTermRenderer, _) -> parse syntaxParser blob >>= decorate (syntaxDeclarationAlgebra blob) >>= render (renderToCTerm blob)
(JSONTermRenderer, Just Language.Markdown) -> parse markdownParser blob >>= decorate constructorLabel >>= render (renderJSONTerm blob)
@ -75,7 +75,7 @@ diffBlobPairs renderer = fmap toOutput . distributeFoldMap (diffBlobPair rendere
diffBlobPair :: DiffRenderer output -> Both Blob -> Task output
diffBlobPair renderer blobs = case (renderer, effectiveLanguage) of
(ToCDiffRenderer, Just Language.Markdown) -> run (\ blob -> parse markdownParser blob >>= decorate (markupSectionAlgebra blob)) diffRecursively (renderToCDiff blobs)
(ToCDiffRenderer, Just Language.Python) -> run (\ blob -> parse pythonParser blob >>= decorate (declarationAlgebra blob) . hoistTerm (weaken :: Union fs a -> Union (Declaration.Method ': fs) a)) diffRecursively (renderToCDiff blobs)
(ToCDiffRenderer, Just Language.Python) -> run (\ blob -> parse pythonParser blob >>= decorate (declarationAlgebra blob)) diffRecursively (renderToCDiff blobs)
(ToCDiffRenderer, Just Language.TypeScript) -> run (\ blob -> parse typescriptParser blob >>= decorate (declarationAlgebra blob)) diffRecursively (renderToCDiff blobs)
(ToCDiffRenderer, _) -> run (\ blob -> parse syntaxParser blob >>= decorate (syntaxDeclarationAlgebra blob)) diffTerms (renderToCDiff blobs)
(JSONDiffRenderer, Just Language.Markdown) -> run (parse markdownParser) diffRecursively (renderJSONDiff blobs)
@ -100,8 +100,11 @@ diffBlobPair renderer blobs = case (renderer, effectiveLanguage) of
run :: Functor syntax => (Blob -> Task (Term syntax ann)) -> (Term syntax ann -> Term syntax ann -> Diff syntax ann ann) -> (Diff syntax ann ann -> output) -> Task output
run parse diff renderer = distributeFor blobs parse >>= runBothWith (diffTermPair blobs diff) >>= render renderer
diffRecursively :: (Eq1 syntax, GAlign syntax, Show1 syntax, Traversable syntax, Diffable syntax) => Term syntax (Record fields1) -> Term syntax (Record fields2) -> Diff syntax (Record fields1) (Record fields2)
diffRecursively = decoratingWith constructorNameAndConstantFields constructorNameAndConstantFields (diffTermsWith algorithmForTerms comparableByConstructor)
diffRecursively :: (Declaration.Method :< fs, Declaration.Function :< fs, Apply Eq1 fs, Apply GAlign fs, Apply Show1 fs, Apply Foldable fs, Apply Functor fs, Apply Traversable fs, Apply Diffable fs)
=> Term (Union fs) (Record fields1)
-> Term (Union fs) (Record fields2)
-> Diff (Union fs) (Record fields1) (Record fields2)
diffRecursively = decoratingWith constructorNameAndConstantFields constructorNameAndConstantFields (diffTermsWith algorithmForTerms comparableByConstructor equivalentTerms)
-- | A task to diff a pair of 'Term's, producing insertion/deletion 'Patch'es for non-existent 'Blob's.
diffTermPair :: Functor syntax => Both Blob -> Differ syntax ann1 ann2 -> Term syntax ann1 -> Term syntax ann2 -> Task (Diff syntax ann1 ann2)

View File

@ -41,7 +41,8 @@ diffWithParser :: (HasField fields Data.Span.Span,
Apply Eq1 fs, Apply Show1 fs,
Apply Traversable fs, Apply Functor fs,
Apply Foldable fs, Apply Diffable fs,
GAlign (Data.Union.Union fs)) =>
Apply GAlign fs
) =>
Parser (Term (Data.Union.Union fs) (Record fields))
-> Both Blob
-> Task (Diff (Union fs) (Record (Maybe Declaration ': fields)) (Record (Maybe Declaration ': fields)))
@ -49,6 +50,9 @@ diffWithParser parser = run (\ blob -> parse parser blob >>= decorate (declarati
where
run parse sourceBlobs = distributeFor sourceBlobs parse >>= runBothWith (diffTermPair sourceBlobs diffRecursively)
diffRecursively :: (Eq1 f, GAlign f, Show1 f, Traversable f, Diffable f) => Term f (Record fields) -> Term f (Record fields) -> Diff f (Record fields) (Record fields)
diffRecursively = decoratingWith constructorNameAndConstantFields constructorNameAndConstantFields (diffTermsWith algorithmForTerms comparableByConstructor)
diffRecursively :: (Declaration.Method :< fs, Declaration.Function :< fs, Apply Eq1 fs, Apply GAlign fs, Apply Show1 fs, Apply Foldable fs, Apply Functor fs, Apply Traversable fs, Apply Diffable fs)
=> Term (Union fs) (Record fields1)
-> Term (Union fs) (Record fields2)
-> Diff (Union fs) (Record fields1) (Record fields2)
diffRecursively = decoratingWith constructorNameAndConstantFields constructorNameAndConstantFields (diffTermsWith algorithmForTerms comparableByConstructor equivalentTerms)

View File

@ -34,12 +34,12 @@ spec = parallel $ do
\ (as, bs) -> let tas = decorate <$> (as :: [Term Syntax (Record '[Category])])
tbs = decorate <$> (bs :: [Term Syntax (Record '[Category])])
root = termIn (Program :. Nil) . Indexed
diff = merge ((Program :. Nil, Program :. Nil)) (Indexed (stripDiff . diffThese <$> rws canCompare tas tbs)) in
diff = merge ((Program :. Nil, Program :. Nil)) (Indexed (stripDiff . diffThese <$> rws canCompare (equalTerms canCompare) tas tbs)) in
(beforeTerm diff, afterTerm diff) `shouldBe` (Just (root (stripTerm <$> tas)), Just (root (stripTerm <$> tbs)))
it "produces unbiased insertions within branches" $
let (a, b) = (decorate (Term ((StringLiteral :. Nil) `In` Indexed [ Term ((StringLiteral :. Nil) `In` Leaf "a") ])), decorate (Term ((StringLiteral :. Nil) `In` Indexed [ Term ((StringLiteral :. Nil) `In` Leaf "b") ]))) in
fmap (bimap stripTerm stripTerm) (rws canCompare [ b ] [ a, b ]) `shouldBe` fmap (bimap stripTerm stripTerm) [ That a, These b b ]
fmap (bimap stripTerm stripTerm) (rws canCompare (equalTerms canCompare) [ b ] [ a, b ]) `shouldBe` fmap (bimap stripTerm stripTerm) [ That a, These b b ]
where canCompare a b = termAnnotation a == termAnnotation b

View File

@ -1,18 +1,12 @@
(Program
{+(Annotation
{+(Annotation
{+(Function
{+(Identifier)+}
{+(Identifier)+}
{+(Identifier)+}
{+(
{+(Identifier)+})+})+}
{+(Empty)+})+}
{+(Identifier)+})+}
(Annotation
(Annotation
(Function
{ (Identifier)
->(Identifier) }
{-(Identifier)-}
(Identifier)
{+(Identifier)+}
(
{ (Identifier)
->(Identifier) }))

View File

@ -1,42 +1,42 @@
(Program
{+(Annotation
{+(Annotation
{+(Function
{+(Identifier)+}
{+(
{+(Identifier)+})+})+}
{+(Empty)+})+}
{+(Identifier)+})+}
(Annotation
(Annotation
(Function
{ (Identifier)
->(Identifier) }
{+(Identifier)+}
(Identifier)
{-(Identifier)-}
(
{ (Identifier)
->(Identifier) }))
(Empty))
(Identifier))
(Annotation
(Annotation
(Function
{ (Identifier)
->(Identifier) }
{+(Identifier)+}
(
{ (Identifier)
->(Identifier) }))
(Empty))
(Identifier))
{-(Annotation
{-(Annotation
{-(Function
{-(Identifier)-}
{-(Identifier)-}
{-(Identifier)-}
{-(
{-(Identifier)-})-})-}
{-(Empty)-})-}
{-(Identifier)-})-})
{-(Identifier)-})-}
(Annotation
(Annotation
(Function
(Identifier)
(
{ (Identifier)
->(Identifier) }))
(Empty))
(Identifier))
(Annotation
(Annotation
(Function
{ (Identifier)
->(Identifier) }
{+(Identifier)+}
{+(Identifier)+}
{-(Identifier)-}
(
{ (Identifier)
->(Identifier) }))
(Empty))
(Identifier))
{+(Annotation
{+(Annotation
{+(Function
{+(Identifier)+}
{+(Identifier)+}
{+(
{+(Identifier)+})+})+}
{+(Empty)+})+}
{+(Identifier)+})+})

View File

@ -1,21 +1,20 @@
(Program
{+(Annotation
{+(Function
{+(Identifier)+}
{+(Identifier)+}
{+(Identifier)+}
{+(
{+(Identifier)+})+})+}
{+(Empty)+})+}
(Annotation
(Function
{ (Identifier)
->(Identifier) }
(
(Identifier)))
(Empty))
{-(Annotation
{-(Function
{-(Identifier)-}
{-(
{-(Identifier)-})-})-}
{-(Empty)-})-}
{-(Annotation
{-(Function
{-(Identifier)-}
{-(Identifier)-}
{-(
{-(Identifier)-})-})-}
{-(Empty)-})-}
(Annotation
(Function
(Identifier)
{ (Identifier)
->(Identifier) }
{ (Identifier)
@ -27,23 +26,16 @@
{+(Annotation
{+(Function
{+(Identifier)+}
{+(Annotation
{+(Assignment
{+(Identifier)+}
{+(Integer)+})+}
{+(Identifier)+})+}
{+(
{+(Identifier)+})+})+}
{+(Empty)+})+}
{+(Annotation
{+(Function
{+(Identifier)+}
{+(Identifier)+}
{+(
{+(Identifier)+})+})+}
{+(Empty)+})+}
{-(Annotation
{-(Function
{-(Identifier)-}
{-(Identifier)-}
{-(Identifier)-}
{-(
{-(Identifier)-})-})-}
{-(Empty)-})-}
{-(Annotation
{-(Function
{-(Identifier)-}
@ -53,15 +45,18 @@
{-(
{-(Identifier)-})-})-}
{-(Empty)-})-}
{-(Annotation
{-(Function
{-(Identifier)-}
{-(Annotation
{-(Assignment
{-(Identifier)-}
{-(TextElement)-})-}
{-(Identifier)-})-}
{-(Identifier)-}
{-(
{-(Identifier)-})-})-}
{-(Empty)-})-})
(Annotation
(Function
(Identifier)
(Annotation
(Assignment
(Identifier)
{ (TextElement)
->(Integer) })
{ (Identifier)
->(Identifier) })
{ (Identifier)
->(Identifier) }
(
(Identifier)))
(Empty)))

View File

@ -1,24 +1,29 @@
(Program
{+(Annotation
{+(Function
{+(Identifier)+}
{+(
{+(Identifier)+})+})+}
{+(Empty)+})+}
{+(Annotation
{+(Function
{+(Identifier)+}
{+(Identifier)+}
{+(
{+(Identifier)+})+})+}
{+(Empty)+})+}
(Annotation
(Function
{ (Identifier)
->(Identifier) }
{-(Identifier)-}
{-(Identifier)-}
(
{+(Identifier)+}
{-(Identifier)-}))
(Empty))
(Annotation
(Function
(Identifier)
{+(Identifier)+}
(
{+(Identifier)+}
{-(Identifier)-}))
(Empty))
(Annotation
(Function
{ (Identifier)
->(Identifier) }
{ (Identifier)
->(Identifier) }
{+(Identifier)+}
(
{+(Identifier)+}
{-(Identifier)-}))
@ -32,40 +37,18 @@
{+(
{+(Identifier)+})+})+}
{+(Empty)+})+}
{+(Annotation
{+(Function
{+(Identifier)+}
{+(Annotation
{+(Assignment
{+(Identifier)+}
{+(TextElement)+})+}
{+(Identifier)+})+}
{+(Identifier)+}
{+(
{+(Identifier)+})+})+}
{+(Empty)+})+}
{-(Annotation
{-(Function
{-(Identifier)-}
{-(
{-(Identifier)-})-})-}
{-(Empty)-})-}
{-(Annotation
{-(Function
{-(Identifier)-}
{-(Identifier)-}
{-(
{-(Identifier)-})-})-}
{-(Empty)-})-}
{-(Annotation
{-(Function
{-(Identifier)-}
{-(Annotation
{-(Assignment
{-(Identifier)-}
{-(Integer)-})-}
{-(Identifier)-})-}
{-(Identifier)-}
{-(
{-(Identifier)-})-})-}
{-(Empty)-})-})
(Annotation
(Function
(Identifier)
(Annotation
(Assignment
(Identifier)
{ (Integer)
->(TextElement) })
{ (Identifier)
->(Identifier) })
{ (Identifier)
->(Identifier) }
(
(Identifier)))
(Empty)))