ast-path (empty) → 0.1.2
raw patch · 7 files changed
+302/−0 lines, 7 filesdep +ast-pathdep +basedep +tastysetup-changed
Dependencies added: ast-path, base, tasty, tasty-hunit
Files
- ChangeLog.md +3/−0
- LICENSE +30/−0
- README.md +21/−0
- Setup.hs +2/−0
- ast-path.cabal +55/−0
- src/Data/ASTPath.hs +100/−0
- test/Main.hs +91/−0
+ ChangeLog.md view
@@ -0,0 +1,3 @@+## 0.1.0++Initial version
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Keito Kajitani (c) 2019++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Keito Kajitani nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,21 @@+# ast-path++AST-path is a representation for predicting program properties.++AST-path is described in the paper "A General Path-Based Representation for Predicting Program Properties" (PLDI'2018) <https://arxiv.org/abs/1803.09544>+and used at <https://code2vec.org/> and at <https://code2seq.org/>.++```+{-# LANGUAGE DeriveGeneric #-}+import Data.ASTPath++data Tree a = Leaf a | Node (Tree a) (Tree a)+ deriving (Eq, Show, Generic)++instance AST a => AST (Tree a)+instance AST Int where+ astPathWithHalf = terminalPath show++>>> astPath $ Node (Leaf 0) (Node (Leaf 1) (Leaf 2))+[("Node",["Leaf","1"],["Leaf","2"]),("Node",["Leaf","0"],["Node","Leaf","1"]),("Node",["Leaf","0"],["Node","Leaf","2"])]+```
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ ast-path.cabal view
@@ -0,0 +1,55 @@+cabal-version: 1.12++-- This file has been generated from package.yaml by hpack version 0.31.1.+--+-- see: https://github.com/sol/hpack+--+-- hash: 7286c954518553459704368e3c5eb84afe6a8f7181d03ce1aba6dda8e981cc73++name: ast-path+version: 0.1.2+synopsis: vocabulary representation for predicting program properties++description: Please see the README on GitHub at <https://github.com/ijaketak/ast-path#readme>+category: Data, Natural Language Processing+homepage: https://github.com/ijaketak/ast-path#readme+bug-reports: https://github.com/ijaketak/ast-path/issues+author: Keito Kajitani+maintainer: ijaketak@gmail.com+copyright: 2019 Keito Kajitani+license: BSD3+license-file: LICENSE+build-type: Simple+extra-source-files:+ README.md+ ChangeLog.md++source-repository head+ type: git+ location: https://github.com/ijaketak/ast-path++library+ exposed-modules:+ Data.ASTPath+ other-modules:+ Paths_ast_path+ hs-source-dirs:+ src+ build-depends:+ base >=4.7 && <5+ default-language: Haskell2010++test-suite ast-path-test+ type: exitcode-stdio-1.0+ main-is: Main.hs+ other-modules:+ Paths_ast_path+ hs-source-dirs:+ test+ ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wno-missing-methods+ build-depends:+ ast-path+ , base >=4.7 && <5+ , tasty+ , tasty-hunit+ default-language: Haskell2010
+ src/Data/ASTPath.hs view
@@ -0,0 +1,100 @@+-- | AST-path is a representation for predicting program properties.++{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeSynonymInstances #-}++module Data.ASTPath+ ( type HalfPath+ , type ASTPath+ , astPath+ , AST(..)+ , treePath+ , terminalPath+ , AST'(..)+ ) where++import GHC.Generics++type HalfPath = [String]++-- | (top node, [..., start node], [..., end node])+type ASTPath = (String, HalfPath, HalfPath)++-- | Typeclass for tree or terminal node.+class AST a where+ {-# MINIMAL astPathWithHalf #-}+ -- | Generate paths and half paths for recursion.+ astPathWithHalf+ :: a -- ^ current tree+ -> String -- ^ label of current root node+ -> ([ASTPath], [HalfPath]) -- ^ paths and half paths+ default astPathWithHalf :: (Generic a, AST' (Rep a)) => a -> String -> ([ASTPath], [HalfPath])+ astPathWithHalf = treePath++-- | Default implementation for tree type.+treePath :: forall a. (Generic a, AST' (Rep a)) => a -> String -> ([ASTPath], [HalfPath])+treePath a c = astPathWithHalf' (from a :: Rep a a) c++-- | Typical implementation for terminal node type.+terminalPath :: (a -> String) -> a -> String -> ([ASTPath], [HalfPath])+terminalPath f x _ = ([], [[f x]])++-- | Generate AST-paths from tree.+astPath :: AST a => a -> [ASTPath]+astPath a = fst $ astPathWithHalf a undefined++-- | Class of generic representation types that can be parsed into paths.+class AST' f where+ -- | Default implementation for generic instances of `AST`.+ astPathWithHalf' :: f a -> String -> ([ASTPath], [HalfPath])++instance AST' V1 where+ astPathWithHalf' _ _ = undefined++instance AST' U1 where+ astPathWithHalf' _ _ = ([], [])++instance (AST' f, AST' g) => AST' (f :+: g) where+ astPathWithHalf' (L1 a) = astPathWithHalf' a+ astPathWithHalf' (R1 a) = astPathWithHalf' a++instance (AST' f, AST' g) => AST' (f :*: g) where+ astPathWithHalf' (a :*: b) c = (ps, hs)+ where+ (psa, hsa) = astPathWithHalf' a c+ (psb, hsb) = astPathWithHalf' b c+ ps = psa ++ psb ++ [ (c, p1, p2) | p1 <- hsa, p2 <- hsb ]+ hs = hsa ++ hsb++instance (AST a) => AST' (K1 i a) where+ astPathWithHalf' (K1 a) = astPathWithHalf (a :: a)++instance (AST' f, Datatype d) => AST' (D1 d f) where+ astPathWithHalf' (M1 a) = astPathWithHalf' a++instance (AST' f, Constructor c) => AST' (C1 c f) where+ astPathWithHalf' (M1 a) _ = (ps, map (c:) hs)+ where+ (ps, hs) = astPathWithHalf' a c+ c = conName (undefined :: t c f a)++instance (AST' f, Selector s) => AST' (S1 s f) where+ astPathWithHalf' (M1 a) = astPathWithHalf' a++-- | Constructor of list type is ignored, same as generic product type.+-- Hence list type itself cannot be used with `astPath`.+-- If want to use, supply root node label.+instance AST a => AST [a] where+ astPathWithHalf [] _ = ([], [])+ astPathWithHalf (x:xs) c = (ps, hs)+ where+ (psh, hsh) = astPathWithHalf x c+ (pst, hst) = astPathWithHalf xs c+ ps = psh ++ pst ++ [ (c, p1, p2) | p1 <- hsh, p2 <- hst ]+ hs = hsh ++ hst
+ test/Main.hs view
@@ -0,0 +1,91 @@+{-# LANGUAGE DeriveGeneric #-}++module Main where++import Data.ASTPath+import GHC.Generics+import Test.Tasty+import Test.Tasty.HUnit++data Tree a = Leaf a | Node (Tree a) (Tree a)+ deriving (Eq, Show, Generic)++data Exp2 a+ = Val a+ | Term (Exp1 a)+ | Add [Exp2 a]+ deriving (Eq, Show, Generic)++data Exp1 a+ = Par (Exp2 a)+ | Mul [Exp1 a]+ deriving (Eq, Show, Generic)++instance AST a => AST (Tree a)+instance AST a => AST (Exp1 a)+instance AST a => AST (Exp2 a)++instance AST Int where+ astPathWithHalf = terminalPath show++main :: IO ()+main = do+ defaultMain $ unitTests++unitTests :: TestTree+unitTests = testGroup "unit tests"+ [ testCase "simple tree" $ do+ let tr :: Tree Int+ tr = Node (Leaf 0) (Leaf 1)+ path = astPath tr+ n = "Node"+ l = "Leaf"+ assertBool "single path" $+ (n, [l, "0"], [l, "1"]) `elem` path+ , testCase "complex tree" $ do+ let tr :: Tree Int+ tr = Node (Leaf 0) (Node (Leaf 1) (Node (Leaf 2) (Leaf 3)))+ path = astPath tr+ n = "Node"+ l = "Leaf"+ assertBool "path 1" $+ (n, [l, "2"], [l, "3"]) `elem` path+ assertBool "path 2" $+ (n, [l, "1"], [n, l, "2"]) `elem` path+ assertBool "path 3" $+ (n, [l, "1"], [n, l, "3"]) `elem` path+ assertBool "path 4" $+ (n, [l, "0"], [n, l, "1"]) `elem` path+ assertBool "path 5" $+ (n, [l, "0"], [n, n, l, "2"]) `elem` path+ assertBool "path 6" $+ (n, [l, "0"], [n, n, l, "3"]) `elem` path+ , testCase "arithmetics" $ do+ let ex :: Exp1 Int+ ex = Mul [Par (Add [Val 5,Val 3]), Par (Add [Val 4, Val 2,Val 1])]+ path = astPath ex+ v = "Val"+ p = "Par"+ a = "Add"+ m = "Mul"+ assertBool "path 1" $+ (a, [v, "5"], [v, "3"]) `elem` path+ assertBool "path 2" $+ (a, [v, "2"], [v, "1"]) `elem` path+ assertBool "path 3" $+ (a, [v, "4"], [v, "2"]) `elem` path+ assertBool "path 4" $+ (a, [v, "4"], [v, "1"]) `elem` path+ assertBool "path 5" $+ (m, [p, a, v, "5"], [p, a, v, "4"]) `elem` path+ assertBool "path 6" $+ (m, [p, a, v, "5"], [p, a, v, "2"]) `elem` path+ assertBool "path 7" $+ (m, [p, a, v, "5"], [p, a, v, "1"]) `elem` path+ assertBool "path 8" $+ (m, [p, a, v, "3"], [p, a, v, "4"]) `elem` path+ assertBool "path 9" $+ (m, [p, a, v, "3"], [p, a, v, "2"]) `elem` path+ assertBool "path 10" $+ (m, [p, a, v, "3"], [p, a, v, "1"]) `elem` path+ ]