diff --git a/eo-phi-normalizer/Setup.hs b/eo-phi-normalizer/Setup.hs index f73408725..0955ac668 100644 --- a/eo-phi-normalizer/Setup.hs +++ b/eo-phi-normalizer/Setup.hs @@ -21,6 +21,7 @@ main = defaultMainWithHooks $ simpleUserHooks , postConf = \args flags packageDesc localBuildInfo -> do #ifndef mingw32_HOST_OS _ <- system "bnfc -d -p Language.EO.Phi --generic -o src/ grammar/EO/Phi/Syntax.cf" + _ <- system "bnfc -d -p Language.EO.Phi.Rules --generic -o src/ grammar/EO/Phi/Rules/Syntax.cf" #endif postConf simpleUserHooks args flags packageDesc localBuildInfo } diff --git a/eo-phi-normalizer/eo-phi-normalizer.cabal b/eo-phi-normalizer/eo-phi-normalizer.cabal index dae1d7b14..d08d8769d 100644 --- a/eo-phi-normalizer/eo-phi-normalizer.cabal +++ b/eo-phi-normalizer/eo-phi-normalizer.cabal @@ -35,6 +35,11 @@ library Language.EO.Phi Language.EO.Phi.Normalize Language.EO.Phi.Rules.Common + Language.EO.Phi.Rules.Syntax.Abs + Language.EO.Phi.Rules.Syntax.Lex + Language.EO.Phi.Rules.Syntax.Par + Language.EO.Phi.Rules.Syntax.Print + Language.EO.Phi.Rules.Yaml Language.EO.Phi.Syntax Language.EO.Phi.Syntax.Abs Language.EO.Phi.Syntax.Lex diff --git a/eo-phi-normalizer/grammar/EO/Phi/Rules/Syntax.cf b/eo-phi-normalizer/grammar/EO/Phi/Rules/Syntax.cf new file mode 100644 index 000000000..25669d8ad --- /dev/null +++ b/eo-phi-normalizer/grammar/EO/Phi/Rules/Syntax.cf @@ -0,0 +1,47 @@ +-- ========================================================== +-- BNFC grammar for φ-programs (translated from EO) +-- ========================================================== +-- +-- This is a non-ambiguous grammar for φ-programs. + +token Bytes ({"--"} | ["0123456789ABCDEF"] ["0123456789ABCDEF"] {"-"} | ["0123456789ABCDEF"] ["0123456789ABCDEF"] ({"-"} ["0123456789ABCDEF"] ["0123456789ABCDEF"])+) ; +token Function upper (char - [" \r\n\t,.|':;!-?][}{)(⟧⟦"])* ; +token LabelId lower (char - [" \r\n\t,.|':;!-?][}{)(⟧⟦"])* ; +token AlphaIndex ({"α0"} | {"α"} (digit - ["0"]) (digit)* ) ; +token MetaId {"!"} (char - [" \r\n\t,.|':;!-?][}{)(⟧⟦"])* ; + +Program. Program ::= "{" [Binding] "}" ; + +Formation. Object ::= "⟦" [Binding] "⟧" ; +Application. Object ::= Object "(" [Binding] ")" ; +ObjectDispatch. Object ::= Object "." Attribute ; +GlobalDispatch. Object ::= "Φ" "." Attribute ; +ThisDispatch. Object ::= "ξ" "." Attribute ; +Termination. Object ::= "⊥" ; +MetaObject. Object ::= MetaId ; + +AlphaBinding. Binding ::= Attribute "↦" Object ; +EmptyBinding. Binding ::= Attribute "↦" "∅" ; +DeltaBinding. Binding ::= "Δ" "⤍" Bytes ; +LambdaBinding. Binding ::= "λ" "⤍" Function ; +MetaBindings. Binding ::= MetaId ; +separator Binding "," ; + +Phi. Attribute ::= "φ" ; -- decoratee object +Rho. Attribute ::= "ρ" ; -- parent object +Sigma. Attribute ::= "σ" ; -- home object +VTX. Attribute ::= "ν" ; -- the vertex identifier (an object that represents the unique identifier of the containing object) +Label. Attribute ::= LabelId ; +Alpha. Attribute ::= AlphaIndex ; +MetaAttr. Attribute ::= MetaId ; + +PeeledObject. PeeledObject ::= ObjectHead [ObjectAction] ; + +HeadFormation. ObjectHead ::= "⟦" [Binding] "⟧" ; +HeadGlobal. ObjectHead ::= "Φ" ; +HeadThis. ObjectHead ::= "ξ" ; +HeadTermination. ObjectHead ::= "⊥" ; + +ActionApplication. ObjectAction ::= "(" [Binding] ")" ; +ActionDispatch. ObjectAction ::= "." Attribute ; +separator ObjectAction "" ; diff --git a/eo-phi-normalizer/package.yaml b/eo-phi-normalizer/package.yaml index da1735273..10bda794b 100644 --- a/eo-phi-normalizer/package.yaml +++ b/eo-phi-normalizer/package.yaml @@ -63,6 +63,9 @@ library: - Language.EO.Phi.Syntax.Test - Language.EO.Phi.Syntax.ErrM - Language.EO.Phi.Syntax.Skel + - Language.EO.Phi.Rules.Syntax.Test + - Language.EO.Phi.Rules.Syntax.ErrM + - Language.EO.Phi.Rules.Syntax.Skel executables: normalize-phi: diff --git a/eo-phi-normalizer/src/Language/EO/Phi/Rules/Syntax/Abs.hs b/eo-phi-normalizer/src/Language/EO/Phi/Rules/Syntax/Abs.hs new file mode 100644 index 000000000..7d6fbaa90 --- /dev/null +++ b/eo-phi-normalizer/src/Language/EO/Phi/Rules/Syntax/Abs.hs @@ -0,0 +1,74 @@ +-- File generated by the BNF Converter (bnfc 2.9.5). + +{-# LANGUAGE DeriveDataTypeable #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} + +-- | The abstract syntax of language Syntax. + +module Language.EO.Phi.Rules.Syntax.Abs where + +import Prelude (String) +import qualified Prelude as C (Eq, Ord, Show, Read) +import qualified Data.String + +import qualified Data.Data as C (Data, Typeable) +import qualified GHC.Generics as C (Generic) + +data Program = Program [Binding] + deriving (C.Eq, C.Ord, C.Show, C.Read, C.Data, C.Typeable, C.Generic) + +data Object + = Formation [Binding] + | Application Object [Binding] + | ObjectDispatch Object Attribute + | GlobalDispatch Attribute + | ThisDispatch Attribute + | Termination + | MetaObject MetaId + deriving (C.Eq, C.Ord, C.Show, C.Read, C.Data, C.Typeable, C.Generic) + +data Binding + = AlphaBinding Attribute Object + | EmptyBinding Attribute + | DeltaBinding Bytes + | LambdaBinding Function + | MetaBindings MetaId + deriving (C.Eq, C.Ord, C.Show, C.Read, C.Data, C.Typeable, C.Generic) + +data Attribute + = Phi + | Rho + | Sigma + | VTX + | Label LabelId + | Alpha AlphaIndex + | MetaAttr MetaId + deriving (C.Eq, C.Ord, C.Show, C.Read, C.Data, C.Typeable, C.Generic) + +data PeeledObject = PeeledObject ObjectHead [ObjectAction] + deriving (C.Eq, C.Ord, C.Show, C.Read, C.Data, C.Typeable, C.Generic) + +data ObjectHead + = HeadFormation [Binding] | HeadGlobal | HeadThis | HeadTermination + deriving (C.Eq, C.Ord, C.Show, C.Read, C.Data, C.Typeable, C.Generic) + +data ObjectAction + = ActionApplication [Binding] | ActionDispatch Attribute + deriving (C.Eq, C.Ord, C.Show, C.Read, C.Data, C.Typeable, C.Generic) + +newtype Bytes = Bytes String + deriving (C.Eq, C.Ord, C.Show, C.Read, C.Data, C.Typeable, C.Generic, Data.String.IsString) + +newtype Function = Function String + deriving (C.Eq, C.Ord, C.Show, C.Read, C.Data, C.Typeable, C.Generic, Data.String.IsString) + +newtype LabelId = LabelId String + deriving (C.Eq, C.Ord, C.Show, C.Read, C.Data, C.Typeable, C.Generic, Data.String.IsString) + +newtype AlphaIndex = AlphaIndex String + deriving (C.Eq, C.Ord, C.Show, C.Read, C.Data, C.Typeable, C.Generic, Data.String.IsString) + +newtype MetaId = MetaId String + deriving (C.Eq, C.Ord, C.Show, C.Read, C.Data, C.Typeable, C.Generic, Data.String.IsString) + diff --git a/eo-phi-normalizer/src/Language/EO/Phi/Rules/Syntax/Doc.txt b/eo-phi-normalizer/src/Language/EO/Phi/Rules/Syntax/Doc.txt new file mode 100644 index 000000000..d7e8c6197 --- /dev/null +++ b/eo-phi-normalizer/src/Language/EO/Phi/Rules/Syntax/Doc.txt @@ -0,0 +1,95 @@ +The Language Syntax +BNF Converter + + +%Process by txt2tags to generate html or latex + + + +This document was automatically generated by the //BNF-Converter//. It was generated together with the lexer, the parser, and the abstract syntax module, which guarantees that the document matches with the implementation of the language (provided no hand-hacking has taken place). + +==The lexical structure of Syntax== + +===Literals=== + + + + + + +Bytes literals are recognized by the regular expression +`````{"--"} | ["0123456789ABCDEF"] ["0123456789ABCDEF"] '-' | ["0123456789ABCDEF"] ["0123456789ABCDEF"] ('-' ["0123456789ABCDEF"] ["0123456789ABCDEF"])+````` + +Function literals are recognized by the regular expression +`````upper (char - [" + !'(),-.:;?[]{|}⟦⟧"])*````` + +LabelId literals are recognized by the regular expression +`````lower (char - [" + !'(),-.:;?[]{|}⟦⟧"])*````` + +AlphaIndex literals are recognized by the regular expression +`````{"α0"} | 'α' (digit - '0') digit*````` + +MetaId literals are recognized by the regular expression +`````'!' (char - [" + !'(),-.:;?[]{|}⟦⟧"])*````` + + +===Reserved words and symbols=== +The set of reserved words is the set of terminals appearing in the grammar. Those reserved words that consist of non-letter characters are called symbols, and they are treated in a different way from those that are similar to identifiers. The lexer follows rules familiar from languages like Haskell, C, and Java, including longest match and spacing conventions. + +The reserved words used in Syntax are the following: + | ``Δ`` | ``Φ`` | ``λ`` | ``ν`` + | ``ξ`` | ``ρ`` | ``σ`` | ``φ`` + +The symbols used in Syntax are the following: + | { | } | ⟦ | ⟧ + | ( | ) | . | ⊥ + | ↦ | ∅ | ⤍ | , + +===Comments=== +There are no single-line comments in the grammar.There are no multiple-line comments in the grammar. + +==The syntactic structure of Syntax== +Non-terminals are enclosed between < and >. +The symbols -> (production), **|** (union) +and **eps** (empty rule) belong to the BNF notation. +All other symbols are terminals. + + | //Program// | -> | ``{`` //[Binding]// ``}`` + | //Object// | -> | ``⟦`` //[Binding]// ``⟧`` + | | **|** | //Object// ``(`` //[Binding]// ``)`` + | | **|** | //Object// ``.`` //Attribute// + | | **|** | ``Φ`` ``.`` //Attribute// + | | **|** | ``ξ`` ``.`` //Attribute// + | | **|** | ``⊥`` + | | **|** | //MetaId// + | //Binding// | -> | //Attribute// ``↦`` //Object// + | | **|** | //Attribute// ``↦`` ``∅`` + | | **|** | ``Δ`` ``⤍`` //Bytes// + | | **|** | ``λ`` ``⤍`` //Function// + | | **|** | //MetaId// + | //[Binding]// | -> | **eps** + | | **|** | //Binding// + | | **|** | //Binding// ``,`` //[Binding]// + | //Attribute// | -> | ``φ`` + | | **|** | ``ρ`` + | | **|** | ``σ`` + | | **|** | ``ν`` + | | **|** | //LabelId// + | | **|** | //AlphaIndex// + | | **|** | //MetaId// + | //PeeledObject// | -> | //ObjectHead// //[ObjectAction]// + | //ObjectHead// | -> | ``⟦`` //[Binding]// ``⟧`` + | | **|** | ``Φ`` + | | **|** | ``ξ`` + | | **|** | ``⊥`` + | //ObjectAction// | -> | ``(`` //[Binding]// ``)`` + | | **|** | ``.`` //Attribute// + | //[ObjectAction]// | -> | **eps** + | | **|** | //ObjectAction// //[ObjectAction]// + + + +%% File generated by the BNF Converter (bnfc 2.9.5). diff --git a/eo-phi-normalizer/src/Language/EO/Phi/Rules/Syntax/ErrM.hs b/eo-phi-normalizer/src/Language/EO/Phi/Rules/Syntax/ErrM.hs new file mode 100644 index 000000000..d65e5bcec --- /dev/null +++ b/eo-phi-normalizer/src/Language/EO/Phi/Rules/Syntax/ErrM.hs @@ -0,0 +1,91 @@ +-- File generated by the BNF Converter (bnfc 2.9.5). + +{-# LANGUAGE CPP #-} + +#if __GLASGOW_HASKELL__ >= 708 +--------------------------------------------------------------------------- +-- Pattern synonyms exist since ghc 7.8. + +-- | BNF Converter: Error Monad. +-- +-- Module for backwards compatibility. +-- +-- The generated parser now uses @'Either' String@ as error monad. +-- This module defines a type synonym 'Err' and pattern synonyms +-- 'Bad' and 'Ok' for 'Left' and 'Right'. + +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE FlexibleInstances #-} + +module Language.EO.Phi.Rules.Syntax.ErrM where + +import Prelude (id, const, Either(..), String) + +import Control.Monad (MonadPlus(..)) +import Control.Applicative (Alternative(..)) +#if __GLASGOW_HASKELL__ >= 808 +import Control.Monad (MonadFail(..)) +#endif + +-- | Error monad with 'String' error messages. +type Err = Either String + +pattern Bad msg = Left msg +pattern Ok a = Right a + +#if __GLASGOW_HASKELL__ >= 808 +instance MonadFail Err where + fail = Bad +#endif + +instance Alternative Err where + empty = Left "Err.empty" + (<|>) Left{} = id + (<|>) x@Right{} = const x + +instance MonadPlus Err where + mzero = empty + mplus = (<|>) + +#else +--------------------------------------------------------------------------- +-- ghc 7.6 and before: use old definition as data type. + +-- | BNF Converter: Error Monad + +-- Copyright (C) 2004 Author: Aarne Ranta +-- This file comes with NO WARRANTY and may be used FOR ANY PURPOSE. + +module Language.EO.Phi.Rules.Syntax.ErrM where + +-- the Error monad: like Maybe type with error msgs + +import Control.Applicative (Applicative(..), Alternative(..)) +import Control.Monad (MonadPlus(..), liftM) + +data Err a = Ok a | Bad String + deriving (Read, Show, Eq, Ord) + +instance Monad Err where + return = Ok + Ok a >>= f = f a + Bad s >>= _ = Bad s + +instance Applicative Err where + pure = Ok + (Bad s) <*> _ = Bad s + (Ok f) <*> o = liftM f o + +instance Functor Err where + fmap = liftM + +instance MonadPlus Err where + mzero = Bad "Err.mzero" + mplus (Bad _) y = y + mplus x _ = x + +instance Alternative Err where + empty = mzero + (<|>) = mplus + +#endif diff --git a/eo-phi-normalizer/src/Language/EO/Phi/Rules/Syntax/Lex.x b/eo-phi-normalizer/src/Language/EO/Phi/Rules/Syntax/Lex.x new file mode 100644 index 000000000..4f7ec1843 --- /dev/null +++ b/eo-phi-normalizer/src/Language/EO/Phi/Rules/Syntax/Lex.x @@ -0,0 +1,271 @@ +-- -*- haskell -*- File generated by the BNF Converter (bnfc 2.9.5). + +-- Lexer definition for use with Alex 3 +{ +{-# OPTIONS -fno-warn-incomplete-patterns #-} +{-# OPTIONS_GHC -w #-} + +{-# LANGUAGE PatternSynonyms #-} + +module Language.EO.Phi.Rules.Syntax.Lex where + +import Prelude + +import qualified Data.Bits +import Data.Char (ord) +import Data.Function (on) +import Data.Word (Word8) +} + +-- Predefined character classes + +$c = [A-Z\192-\221] # [\215] -- capital isolatin1 letter (215 = \times) FIXME +$s = [a-z\222-\255] # [\247] -- small isolatin1 letter (247 = \div ) FIXME +$l = [$c $s] -- letter +$d = [0-9] -- digit +$i = [$l $d _ '] -- identifier character +$u = [. \n] -- universal: any character + +-- Symbols and non-identifier-like reserved words + +@rsyms = \Φ | \ξ | \Δ | \λ | \φ | \ρ | \σ | \ν | \{ | \} | \⟦ | \⟧ | \( | \) | \. | \⊥ | \↦ | \∅ | \⤍ | \, + +:- + +-- Whitespace (skipped) +$white+ ; + +-- Symbols +@rsyms + { tok (eitherResIdent TV) } + +-- token Bytes +\- \- | [0 1 2 3 4 5 6 7 8 9 A B C D E F][0 1 2 3 4 5 6 7 8 9 A B C D E F]\- | [0 1 2 3 4 5 6 7 8 9 A B C D E F][0 1 2 3 4 5 6 7 8 9 A B C D E F](\- [0 1 2 3 4 5 6 7 8 9 A B C D E F][0 1 2 3 4 5 6 7 8 9 A B C D E F]) + + { tok (eitherResIdent T_Bytes) } + +-- token Function +$c [$u # [\t \n \r \ \! \' \( \) \, \- \. \: \; \? \[ \] \{ \| \} \⟦ \⟧]] * + { tok (eitherResIdent T_Function) } + +-- token LabelId +$s [$u # [\t \n \r \ \! \' \( \) \, \- \. \: \; \? \[ \] \{ \| \} \⟦ \⟧]] * + { tok (eitherResIdent T_LabelId) } + +-- token AlphaIndex +α 0 | α [$d # 0]$d * + { tok (eitherResIdent T_AlphaIndex) } + +-- token MetaId +\! [$u # [\t \n \r \ \! \' \( \) \, \- \. \: \; \? \[ \] \{ \| \} \⟦ \⟧]] * + { tok (eitherResIdent T_MetaId) } + +-- Keywords and Ident +$l $i* + { tok (eitherResIdent TV) } + +{ +-- | Create a token with position. +tok :: (String -> Tok) -> (Posn -> String -> Token) +tok f p = PT p . f + +-- | Token without position. +data Tok + = TK {-# UNPACK #-} !TokSymbol -- ^ Reserved word or symbol. + | TL !String -- ^ String literal. + | TI !String -- ^ Integer literal. + | TV !String -- ^ Identifier. + | TD !String -- ^ Float literal. + | TC !String -- ^ Character literal. + | T_Bytes !String + | T_Function !String + | T_LabelId !String + | T_AlphaIndex !String + | T_MetaId !String + deriving (Eq, Show, Ord) + +-- | Smart constructor for 'Tok' for the sake of backwards compatibility. +pattern TS :: String -> Int -> Tok +pattern TS t i = TK (TokSymbol t i) + +-- | Keyword or symbol tokens have a unique ID. +data TokSymbol = TokSymbol + { tsText :: String + -- ^ Keyword or symbol text. + , tsID :: !Int + -- ^ Unique ID. + } deriving (Show) + +-- | Keyword/symbol equality is determined by the unique ID. +instance Eq TokSymbol where (==) = (==) `on` tsID + +-- | Keyword/symbol ordering is determined by the unique ID. +instance Ord TokSymbol where compare = compare `on` tsID + +-- | Token with position. +data Token + = PT Posn Tok + | Err Posn + deriving (Eq, Show, Ord) + +-- | Pretty print a position. +printPosn :: Posn -> String +printPosn (Pn _ l c) = "line " ++ show l ++ ", column " ++ show c + +-- | Pretty print the position of the first token in the list. +tokenPos :: [Token] -> String +tokenPos (t:_) = printPosn (tokenPosn t) +tokenPos [] = "end of file" + +-- | Get the position of a token. +tokenPosn :: Token -> Posn +tokenPosn (PT p _) = p +tokenPosn (Err p) = p + +-- | Get line and column of a token. +tokenLineCol :: Token -> (Int, Int) +tokenLineCol = posLineCol . tokenPosn + +-- | Get line and column of a position. +posLineCol :: Posn -> (Int, Int) +posLineCol (Pn _ l c) = (l,c) + +-- | Convert a token into "position token" form. +mkPosToken :: Token -> ((Int, Int), String) +mkPosToken t = (tokenLineCol t, tokenText t) + +-- | Convert a token to its text. +tokenText :: Token -> String +tokenText t = case t of + PT _ (TS s _) -> s + PT _ (TL s) -> show s + PT _ (TI s) -> s + PT _ (TV s) -> s + PT _ (TD s) -> s + PT _ (TC s) -> s + Err _ -> "#error" + PT _ (T_Bytes s) -> s + PT _ (T_Function s) -> s + PT _ (T_LabelId s) -> s + PT _ (T_AlphaIndex s) -> s + PT _ (T_MetaId s) -> s + +-- | Convert a token to a string. +prToken :: Token -> String +prToken t = tokenText t + +-- | Finite map from text to token organized as binary search tree. +data BTree + = N -- ^ Nil (leaf). + | B String Tok BTree BTree + -- ^ Binary node. + deriving (Show) + +-- | Convert potential keyword into token or use fallback conversion. +eitherResIdent :: (String -> Tok) -> String -> Tok +eitherResIdent tv s = treeFind resWords + where + treeFind N = tv s + treeFind (B a t left right) = + case compare s a of + LT -> treeFind left + GT -> treeFind right + EQ -> t + +-- | The keywords and symbols of the language organized as binary search tree. +resWords :: BTree +resWords = + b "\958" 11 + (b "}" 6 + (b "," 3 (b ")" 2 (b "(" 1 N N) N) (b "{" 5 (b "." 4 N N) N)) + (b "\955" 9 (b "\934" 8 (b "\916" 7 N N) N) (b "\957" 10 N N))) + (b "\8709" 16 + (b "\966" 14 (b "\963" 13 (b "\961" 12 N N) N) (b "\8614" 15 N N)) + (b "\10215" 19 + (b "\10214" 18 (b "\8869" 17 N N) N) (b "\10509" 20 N N))) + where + b s n = B bs (TS bs n) + where + bs = s + +-- | Unquote string literal. +unescapeInitTail :: String -> String +unescapeInitTail = id . unesc . tail . id + where + unesc s = case s of + '\\':c:cs | elem c ['\"', '\\', '\''] -> c : unesc cs + '\\':'n':cs -> '\n' : unesc cs + '\\':'t':cs -> '\t' : unesc cs + '\\':'r':cs -> '\r' : unesc cs + '\\':'f':cs -> '\f' : unesc cs + '"':[] -> [] + c:cs -> c : unesc cs + _ -> [] + +------------------------------------------------------------------- +-- Alex wrapper code. +-- A modified "posn" wrapper. +------------------------------------------------------------------- + +data Posn = Pn !Int !Int !Int + deriving (Eq, Show, Ord) + +alexStartPos :: Posn +alexStartPos = Pn 0 1 1 + +alexMove :: Posn -> Char -> Posn +alexMove (Pn a l c) '\t' = Pn (a+1) l (((c+7) `div` 8)*8+1) +alexMove (Pn a l c) '\n' = Pn (a+1) (l+1) 1 +alexMove (Pn a l c) _ = Pn (a+1) l (c+1) + +type Byte = Word8 + +type AlexInput = (Posn, -- current position, + Char, -- previous char + [Byte], -- pending bytes on the current char + String) -- current input string + +tokens :: String -> [Token] +tokens str = go (alexStartPos, '\n', [], str) + where + go :: AlexInput -> [Token] + go inp@(pos, _, _, str) = + case alexScan inp 0 of + AlexEOF -> [] + AlexError (pos, _, _, _) -> [Err pos] + AlexSkip inp' len -> go inp' + AlexToken inp' len act -> act pos (take len str) : (go inp') + +alexGetByte :: AlexInput -> Maybe (Byte,AlexInput) +alexGetByte (p, c, (b:bs), s) = Just (b, (p, c, bs, s)) +alexGetByte (p, _, [], s) = + case s of + [] -> Nothing + (c:s) -> + let p' = alexMove p c + (b:bs) = utf8Encode c + in p' `seq` Just (b, (p', c, bs, s)) + +alexInputPrevChar :: AlexInput -> Char +alexInputPrevChar (p, c, bs, s) = c + +-- | Encode a Haskell String to a list of Word8 values, in UTF8 format. +utf8Encode :: Char -> [Word8] +utf8Encode = map fromIntegral . go . ord + where + go oc + | oc <= 0x7f = [oc] + + | oc <= 0x7ff = [ 0xc0 + (oc `Data.Bits.shiftR` 6) + , 0x80 + oc Data.Bits..&. 0x3f + ] + + | oc <= 0xffff = [ 0xe0 + (oc `Data.Bits.shiftR` 12) + , 0x80 + ((oc `Data.Bits.shiftR` 6) Data.Bits..&. 0x3f) + , 0x80 + oc Data.Bits..&. 0x3f + ] + | otherwise = [ 0xf0 + (oc `Data.Bits.shiftR` 18) + , 0x80 + ((oc `Data.Bits.shiftR` 12) Data.Bits..&. 0x3f) + , 0x80 + ((oc `Data.Bits.shiftR` 6) Data.Bits..&. 0x3f) + , 0x80 + oc Data.Bits..&. 0x3f + ] +} diff --git a/eo-phi-normalizer/src/Language/EO/Phi/Rules/Syntax/Par.y b/eo-phi-normalizer/src/Language/EO/Phi/Rules/Syntax/Par.y new file mode 100644 index 000000000..c88f6cd27 --- /dev/null +++ b/eo-phi-normalizer/src/Language/EO/Phi/Rules/Syntax/Par.y @@ -0,0 +1,159 @@ +-- -*- haskell -*- File generated by the BNF Converter (bnfc 2.9.5). + +-- Parser definition for use with Happy +{ +{-# OPTIONS_GHC -fno-warn-incomplete-patterns -fno-warn-overlapping-patterns #-} +{-# LANGUAGE PatternSynonyms #-} + +module Language.EO.Phi.Rules.Syntax.Par + ( happyError + , myLexer + , pProgram + , pObject + , pBinding + , pListBinding + , pAttribute + , pPeeledObject + , pObjectHead + , pObjectAction + , pListObjectAction + ) where + +import Prelude + +import qualified Language.EO.Phi.Rules.Syntax.Abs +import Language.EO.Phi.Rules.Syntax.Lex + +} + +%name pProgram Program +%name pObject Object +%name pBinding Binding +%name pListBinding ListBinding +%name pAttribute Attribute +%name pPeeledObject PeeledObject +%name pObjectHead ObjectHead +%name pObjectAction ObjectAction +%name pListObjectAction ListObjectAction +-- no lexer declaration +%monad { Err } { (>>=) } { return } +%tokentype {Token} +%token + '(' { PT _ (TS _ 1) } + ')' { PT _ (TS _ 2) } + ',' { PT _ (TS _ 3) } + '.' { PT _ (TS _ 4) } + '{' { PT _ (TS _ 5) } + '}' { PT _ (TS _ 6) } + 'Δ' { PT _ (TS _ 7) } + 'Φ' { PT _ (TS _ 8) } + 'λ' { PT _ (TS _ 9) } + 'ν' { PT _ (TS _ 10) } + 'ξ' { PT _ (TS _ 11) } + 'ρ' { PT _ (TS _ 12) } + 'σ' { PT _ (TS _ 13) } + 'φ' { PT _ (TS _ 14) } + '↦' { PT _ (TS _ 15) } + '∅' { PT _ (TS _ 16) } + '⊥' { PT _ (TS _ 17) } + '⟦' { PT _ (TS _ 18) } + '⟧' { PT _ (TS _ 19) } + '⤍' { PT _ (TS _ 20) } + L_Bytes { PT _ (T_Bytes $$) } + L_Function { PT _ (T_Function $$) } + L_LabelId { PT _ (T_LabelId $$) } + L_AlphaIndex { PT _ (T_AlphaIndex $$) } + L_MetaId { PT _ (T_MetaId $$) } + +%% + +Bytes :: { Language.EO.Phi.Rules.Syntax.Abs.Bytes } +Bytes : L_Bytes { Language.EO.Phi.Rules.Syntax.Abs.Bytes $1 } + +Function :: { Language.EO.Phi.Rules.Syntax.Abs.Function } +Function : L_Function { Language.EO.Phi.Rules.Syntax.Abs.Function $1 } + +LabelId :: { Language.EO.Phi.Rules.Syntax.Abs.LabelId } +LabelId : L_LabelId { Language.EO.Phi.Rules.Syntax.Abs.LabelId $1 } + +AlphaIndex :: { Language.EO.Phi.Rules.Syntax.Abs.AlphaIndex } +AlphaIndex : L_AlphaIndex { Language.EO.Phi.Rules.Syntax.Abs.AlphaIndex $1 } + +MetaId :: { Language.EO.Phi.Rules.Syntax.Abs.MetaId } +MetaId : L_MetaId { Language.EO.Phi.Rules.Syntax.Abs.MetaId $1 } + +Program :: { Language.EO.Phi.Rules.Syntax.Abs.Program } +Program + : '{' ListBinding '}' { Language.EO.Phi.Rules.Syntax.Abs.Program $2 } + +Object :: { Language.EO.Phi.Rules.Syntax.Abs.Object } +Object + : '⟦' ListBinding '⟧' { Language.EO.Phi.Rules.Syntax.Abs.Formation $2 } + | Object '(' ListBinding ')' { Language.EO.Phi.Rules.Syntax.Abs.Application $1 $3 } + | Object '.' Attribute { Language.EO.Phi.Rules.Syntax.Abs.ObjectDispatch $1 $3 } + | 'Φ' '.' Attribute { Language.EO.Phi.Rules.Syntax.Abs.GlobalDispatch $3 } + | 'ξ' '.' Attribute { Language.EO.Phi.Rules.Syntax.Abs.ThisDispatch $3 } + | '⊥' { Language.EO.Phi.Rules.Syntax.Abs.Termination } + | MetaId { Language.EO.Phi.Rules.Syntax.Abs.MetaObject $1 } + +Binding :: { Language.EO.Phi.Rules.Syntax.Abs.Binding } +Binding + : Attribute '↦' Object { Language.EO.Phi.Rules.Syntax.Abs.AlphaBinding $1 $3 } + | Attribute '↦' '∅' { Language.EO.Phi.Rules.Syntax.Abs.EmptyBinding $1 } + | 'Δ' '⤍' Bytes { Language.EO.Phi.Rules.Syntax.Abs.DeltaBinding $3 } + | 'λ' '⤍' Function { Language.EO.Phi.Rules.Syntax.Abs.LambdaBinding $3 } + | MetaId { Language.EO.Phi.Rules.Syntax.Abs.MetaBindings $1 } + +ListBinding :: { [Language.EO.Phi.Rules.Syntax.Abs.Binding] } +ListBinding + : {- empty -} { [] } + | Binding { (:[]) $1 } + | Binding ',' ListBinding { (:) $1 $3 } + +Attribute :: { Language.EO.Phi.Rules.Syntax.Abs.Attribute } +Attribute + : 'φ' { Language.EO.Phi.Rules.Syntax.Abs.Phi } + | 'ρ' { Language.EO.Phi.Rules.Syntax.Abs.Rho } + | 'σ' { Language.EO.Phi.Rules.Syntax.Abs.Sigma } + | 'ν' { Language.EO.Phi.Rules.Syntax.Abs.VTX } + | LabelId { Language.EO.Phi.Rules.Syntax.Abs.Label $1 } + | AlphaIndex { Language.EO.Phi.Rules.Syntax.Abs.Alpha $1 } + | MetaId { Language.EO.Phi.Rules.Syntax.Abs.MetaAttr $1 } + +PeeledObject :: { Language.EO.Phi.Rules.Syntax.Abs.PeeledObject } +PeeledObject + : ObjectHead ListObjectAction { Language.EO.Phi.Rules.Syntax.Abs.PeeledObject $1 $2 } + +ObjectHead :: { Language.EO.Phi.Rules.Syntax.Abs.ObjectHead } +ObjectHead + : '⟦' ListBinding '⟧' { Language.EO.Phi.Rules.Syntax.Abs.HeadFormation $2 } + | 'Φ' { Language.EO.Phi.Rules.Syntax.Abs.HeadGlobal } + | 'ξ' { Language.EO.Phi.Rules.Syntax.Abs.HeadThis } + | '⊥' { Language.EO.Phi.Rules.Syntax.Abs.HeadTermination } + +ObjectAction :: { Language.EO.Phi.Rules.Syntax.Abs.ObjectAction } +ObjectAction + : '(' ListBinding ')' { Language.EO.Phi.Rules.Syntax.Abs.ActionApplication $2 } + | '.' Attribute { Language.EO.Phi.Rules.Syntax.Abs.ActionDispatch $2 } + +ListObjectAction :: { [Language.EO.Phi.Rules.Syntax.Abs.ObjectAction] } +ListObjectAction + : {- empty -} { [] } | ObjectAction ListObjectAction { (:) $1 $2 } + +{ + +type Err = Either String + +happyError :: [Token] -> Err a +happyError ts = Left $ + "syntax error at " ++ tokenPos ts ++ + case ts of + [] -> [] + [Err _] -> " due to lexer error" + t:_ -> " before `" ++ (prToken t) ++ "'" + +myLexer :: String -> [Token] +myLexer = tokens + +} + diff --git a/eo-phi-normalizer/src/Language/EO/Phi/Rules/Syntax/Print.hs b/eo-phi-normalizer/src/Language/EO/Phi/Rules/Syntax/Print.hs new file mode 100644 index 000000000..6a2327bc9 --- /dev/null +++ b/eo-phi-normalizer/src/Language/EO/Phi/Rules/Syntax/Print.hs @@ -0,0 +1,205 @@ +-- File generated by the BNF Converter (bnfc 2.9.5). + +{-# LANGUAGE CPP #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE LambdaCase #-} +#if __GLASGOW_HASKELL__ <= 708 +{-# LANGUAGE OverlappingInstances #-} +#endif + +-- | Pretty-printer for Language. + +module Language.EO.Phi.Rules.Syntax.Print where + +import Prelude + ( ($), (.) + , Bool(..), (==), (<) + , Int, Integer, Double, (+), (-), (*) + , String, (++) + , ShowS, showChar, showString + , all, elem, foldr, id, map, null, replicate, shows, span + ) +import Data.Char ( Char, isSpace ) +import qualified Language.EO.Phi.Rules.Syntax.Abs + +-- | The top-level printing method. + +printTree :: Print a => a -> String +printTree = render . prt 0 + +type Doc = [ShowS] -> [ShowS] + +doc :: ShowS -> Doc +doc = (:) + +render :: Doc -> String +render d = rend 0 False (map ($ "") $ d []) "" + where + rend + :: Int -- ^ Indentation level. + -> Bool -- ^ Pending indentation to be output before next character? + -> [String] + -> ShowS + rend i p = \case + "[" :ts -> char '[' . rend i False ts + "(" :ts -> char '(' . rend i False ts + "{" :ts -> onNewLine i p . showChar '{' . new (i+1) ts + "}" : ";":ts -> onNewLine (i-1) p . showString "};" . new (i-1) ts + "}" :ts -> onNewLine (i-1) p . showChar '}' . new (i-1) ts + [";"] -> char ';' + ";" :ts -> char ';' . new i ts + t : ts@(s:_) | closingOrPunctuation s + -> pending . showString t . rend i False ts + t :ts -> pending . space t . rend i False ts + [] -> id + where + -- Output character after pending indentation. + char :: Char -> ShowS + char c = pending . showChar c + + -- Output pending indentation. + pending :: ShowS + pending = if p then indent i else id + + -- Indentation (spaces) for given indentation level. + indent :: Int -> ShowS + indent i = replicateS (2*i) (showChar ' ') + + -- Continue rendering in new line with new indentation. + new :: Int -> [String] -> ShowS + new j ts = showChar '\n' . rend j True ts + + -- Make sure we are on a fresh line. + onNewLine :: Int -> Bool -> ShowS + onNewLine i p = (if p then id else showChar '\n') . indent i + + -- Separate given string from following text by a space (if needed). + space :: String -> ShowS + space t s = + case (all isSpace t, null spc, null rest) of + (True , _ , True ) -> [] -- remove trailing space + (False, _ , True ) -> t -- remove trailing space + (False, True, False) -> t ++ ' ' : s -- add space if none + _ -> t ++ s + where + (spc, rest) = span isSpace s + + closingOrPunctuation :: String -> Bool + closingOrPunctuation [c] = c `elem` closerOrPunct + closingOrPunctuation _ = False + + closerOrPunct :: String + closerOrPunct = ")],;" + +parenth :: Doc -> Doc +parenth ss = doc (showChar '(') . ss . doc (showChar ')') + +concatS :: [ShowS] -> ShowS +concatS = foldr (.) id + +concatD :: [Doc] -> Doc +concatD = foldr (.) id + +replicateS :: Int -> ShowS -> ShowS +replicateS n f = concatS (replicate n f) + +-- | The printer class does the job. + +class Print a where + prt :: Int -> a -> Doc + +instance {-# OVERLAPPABLE #-} Print a => Print [a] where + prt i = concatD . map (prt i) + +instance Print Char where + prt _ c = doc (showChar '\'' . mkEsc '\'' c . showChar '\'') + +instance Print String where + prt _ = printString + +printString :: String -> Doc +printString s = doc (showChar '"' . concatS (map (mkEsc '"') s) . showChar '"') + +mkEsc :: Char -> Char -> ShowS +mkEsc q = \case + s | s == q -> showChar '\\' . showChar s + '\\' -> showString "\\\\" + '\n' -> showString "\\n" + '\t' -> showString "\\t" + s -> showChar s + +prPrec :: Int -> Int -> Doc -> Doc +prPrec i j = if j < i then parenth else id + +instance Print Integer where + prt _ x = doc (shows x) + +instance Print Double where + prt _ x = doc (shows x) + +instance Print Language.EO.Phi.Rules.Syntax.Abs.Bytes where + prt _ (Language.EO.Phi.Rules.Syntax.Abs.Bytes i) = doc $ showString i +instance Print Language.EO.Phi.Rules.Syntax.Abs.Function where + prt _ (Language.EO.Phi.Rules.Syntax.Abs.Function i) = doc $ showString i +instance Print Language.EO.Phi.Rules.Syntax.Abs.LabelId where + prt _ (Language.EO.Phi.Rules.Syntax.Abs.LabelId i) = doc $ showString i +instance Print Language.EO.Phi.Rules.Syntax.Abs.AlphaIndex where + prt _ (Language.EO.Phi.Rules.Syntax.Abs.AlphaIndex i) = doc $ showString i +instance Print Language.EO.Phi.Rules.Syntax.Abs.MetaId where + prt _ (Language.EO.Phi.Rules.Syntax.Abs.MetaId i) = doc $ showString i +instance Print Language.EO.Phi.Rules.Syntax.Abs.Program where + prt i = \case + Language.EO.Phi.Rules.Syntax.Abs.Program bindings -> prPrec i 0 (concatD [doc (showString "{"), prt 0 bindings, doc (showString "}")]) + +instance Print Language.EO.Phi.Rules.Syntax.Abs.Object where + prt i = \case + Language.EO.Phi.Rules.Syntax.Abs.Formation bindings -> prPrec i 0 (concatD [doc (showString "\10214"), prt 0 bindings, doc (showString "\10215")]) + Language.EO.Phi.Rules.Syntax.Abs.Application object bindings -> prPrec i 0 (concatD [prt 0 object, doc (showString "("), prt 0 bindings, doc (showString ")")]) + Language.EO.Phi.Rules.Syntax.Abs.ObjectDispatch object attribute -> prPrec i 0 (concatD [prt 0 object, doc (showString "."), prt 0 attribute]) + Language.EO.Phi.Rules.Syntax.Abs.GlobalDispatch attribute -> prPrec i 0 (concatD [doc (showString "\934"), doc (showString "."), prt 0 attribute]) + Language.EO.Phi.Rules.Syntax.Abs.ThisDispatch attribute -> prPrec i 0 (concatD [doc (showString "\958"), doc (showString "."), prt 0 attribute]) + Language.EO.Phi.Rules.Syntax.Abs.Termination -> prPrec i 0 (concatD [doc (showString "\8869")]) + Language.EO.Phi.Rules.Syntax.Abs.MetaObject metaid -> prPrec i 0 (concatD [prt 0 metaid]) + +instance Print Language.EO.Phi.Rules.Syntax.Abs.Binding where + prt i = \case + Language.EO.Phi.Rules.Syntax.Abs.AlphaBinding attribute object -> prPrec i 0 (concatD [prt 0 attribute, doc (showString "\8614"), prt 0 object]) + Language.EO.Phi.Rules.Syntax.Abs.EmptyBinding attribute -> prPrec i 0 (concatD [prt 0 attribute, doc (showString "\8614"), doc (showString "\8709")]) + Language.EO.Phi.Rules.Syntax.Abs.DeltaBinding bytes -> prPrec i 0 (concatD [doc (showString "\916"), doc (showString "\10509"), prt 0 bytes]) + Language.EO.Phi.Rules.Syntax.Abs.LambdaBinding function -> prPrec i 0 (concatD [doc (showString "\955"), doc (showString "\10509"), prt 0 function]) + Language.EO.Phi.Rules.Syntax.Abs.MetaBindings metaid -> prPrec i 0 (concatD [prt 0 metaid]) + +instance Print [Language.EO.Phi.Rules.Syntax.Abs.Binding] where + prt _ [] = concatD [] + prt _ [x] = concatD [prt 0 x] + prt _ (x:xs) = concatD [prt 0 x, doc (showString ","), prt 0 xs] + +instance Print Language.EO.Phi.Rules.Syntax.Abs.Attribute where + prt i = \case + Language.EO.Phi.Rules.Syntax.Abs.Phi -> prPrec i 0 (concatD [doc (showString "\966")]) + Language.EO.Phi.Rules.Syntax.Abs.Rho -> prPrec i 0 (concatD [doc (showString "\961")]) + Language.EO.Phi.Rules.Syntax.Abs.Sigma -> prPrec i 0 (concatD [doc (showString "\963")]) + Language.EO.Phi.Rules.Syntax.Abs.VTX -> prPrec i 0 (concatD [doc (showString "\957")]) + Language.EO.Phi.Rules.Syntax.Abs.Label labelid -> prPrec i 0 (concatD [prt 0 labelid]) + Language.EO.Phi.Rules.Syntax.Abs.Alpha alphaindex -> prPrec i 0 (concatD [prt 0 alphaindex]) + Language.EO.Phi.Rules.Syntax.Abs.MetaAttr metaid -> prPrec i 0 (concatD [prt 0 metaid]) + +instance Print Language.EO.Phi.Rules.Syntax.Abs.PeeledObject where + prt i = \case + Language.EO.Phi.Rules.Syntax.Abs.PeeledObject objecthead objectactions -> prPrec i 0 (concatD [prt 0 objecthead, prt 0 objectactions]) + +instance Print Language.EO.Phi.Rules.Syntax.Abs.ObjectHead where + prt i = \case + Language.EO.Phi.Rules.Syntax.Abs.HeadFormation bindings -> prPrec i 0 (concatD [doc (showString "\10214"), prt 0 bindings, doc (showString "\10215")]) + Language.EO.Phi.Rules.Syntax.Abs.HeadGlobal -> prPrec i 0 (concatD [doc (showString "\934")]) + Language.EO.Phi.Rules.Syntax.Abs.HeadThis -> prPrec i 0 (concatD [doc (showString "\958")]) + Language.EO.Phi.Rules.Syntax.Abs.HeadTermination -> prPrec i 0 (concatD [doc (showString "\8869")]) + +instance Print Language.EO.Phi.Rules.Syntax.Abs.ObjectAction where + prt i = \case + Language.EO.Phi.Rules.Syntax.Abs.ActionApplication bindings -> prPrec i 0 (concatD [doc (showString "("), prt 0 bindings, doc (showString ")")]) + Language.EO.Phi.Rules.Syntax.Abs.ActionDispatch attribute -> prPrec i 0 (concatD [doc (showString "."), prt 0 attribute]) + +instance Print [Language.EO.Phi.Rules.Syntax.Abs.ObjectAction] where + prt _ [] = concatD [] + prt _ (x:xs) = concatD [prt 0 x, prt 0 xs] diff --git a/eo-phi-normalizer/src/Language/EO/Phi/Rules/Syntax/Skel.hs b/eo-phi-normalizer/src/Language/EO/Phi/Rules/Syntax/Skel.hs new file mode 100644 index 000000000..a787b3d4f --- /dev/null +++ b/eo-phi-normalizer/src/Language/EO/Phi/Rules/Syntax/Skel.hs @@ -0,0 +1,84 @@ +-- File generated by the BNF Converter (bnfc 2.9.5). + +-- Templates for pattern matching on abstract syntax + +{-# OPTIONS_GHC -fno-warn-unused-matches #-} + +module Language.EO.Phi.Rules.Syntax.Skel where + +import Prelude (($), Either(..), String, (++), Show, show) +import qualified Language.EO.Phi.Rules.Syntax.Abs + +type Err = Either String +type Result = Err String + +failure :: Show a => a -> Result +failure x = Left $ "Undefined case: " ++ show x + +transBytes :: Language.EO.Phi.Rules.Syntax.Abs.Bytes -> Result +transBytes x = case x of + Language.EO.Phi.Rules.Syntax.Abs.Bytes string -> failure x + +transFunction :: Language.EO.Phi.Rules.Syntax.Abs.Function -> Result +transFunction x = case x of + Language.EO.Phi.Rules.Syntax.Abs.Function string -> failure x + +transLabelId :: Language.EO.Phi.Rules.Syntax.Abs.LabelId -> Result +transLabelId x = case x of + Language.EO.Phi.Rules.Syntax.Abs.LabelId string -> failure x + +transAlphaIndex :: Language.EO.Phi.Rules.Syntax.Abs.AlphaIndex -> Result +transAlphaIndex x = case x of + Language.EO.Phi.Rules.Syntax.Abs.AlphaIndex string -> failure x + +transMetaId :: Language.EO.Phi.Rules.Syntax.Abs.MetaId -> Result +transMetaId x = case x of + Language.EO.Phi.Rules.Syntax.Abs.MetaId string -> failure x + +transProgram :: Language.EO.Phi.Rules.Syntax.Abs.Program -> Result +transProgram x = case x of + Language.EO.Phi.Rules.Syntax.Abs.Program bindings -> failure x + +transObject :: Language.EO.Phi.Rules.Syntax.Abs.Object -> Result +transObject x = case x of + Language.EO.Phi.Rules.Syntax.Abs.Formation bindings -> failure x + Language.EO.Phi.Rules.Syntax.Abs.Application object bindings -> failure x + Language.EO.Phi.Rules.Syntax.Abs.ObjectDispatch object attribute -> failure x + Language.EO.Phi.Rules.Syntax.Abs.GlobalDispatch attribute -> failure x + Language.EO.Phi.Rules.Syntax.Abs.ThisDispatch attribute -> failure x + Language.EO.Phi.Rules.Syntax.Abs.Termination -> failure x + Language.EO.Phi.Rules.Syntax.Abs.MetaObject metaid -> failure x + +transBinding :: Language.EO.Phi.Rules.Syntax.Abs.Binding -> Result +transBinding x = case x of + Language.EO.Phi.Rules.Syntax.Abs.AlphaBinding attribute object -> failure x + Language.EO.Phi.Rules.Syntax.Abs.EmptyBinding attribute -> failure x + Language.EO.Phi.Rules.Syntax.Abs.DeltaBinding bytes -> failure x + Language.EO.Phi.Rules.Syntax.Abs.LambdaBinding function -> failure x + Language.EO.Phi.Rules.Syntax.Abs.MetaBindings metaid -> failure x + +transAttribute :: Language.EO.Phi.Rules.Syntax.Abs.Attribute -> Result +transAttribute x = case x of + Language.EO.Phi.Rules.Syntax.Abs.Phi -> failure x + Language.EO.Phi.Rules.Syntax.Abs.Rho -> failure x + Language.EO.Phi.Rules.Syntax.Abs.Sigma -> failure x + Language.EO.Phi.Rules.Syntax.Abs.VTX -> failure x + Language.EO.Phi.Rules.Syntax.Abs.Label labelid -> failure x + Language.EO.Phi.Rules.Syntax.Abs.Alpha alphaindex -> failure x + Language.EO.Phi.Rules.Syntax.Abs.MetaAttr metaid -> failure x + +transPeeledObject :: Language.EO.Phi.Rules.Syntax.Abs.PeeledObject -> Result +transPeeledObject x = case x of + Language.EO.Phi.Rules.Syntax.Abs.PeeledObject objecthead objectactions -> failure x + +transObjectHead :: Language.EO.Phi.Rules.Syntax.Abs.ObjectHead -> Result +transObjectHead x = case x of + Language.EO.Phi.Rules.Syntax.Abs.HeadFormation bindings -> failure x + Language.EO.Phi.Rules.Syntax.Abs.HeadGlobal -> failure x + Language.EO.Phi.Rules.Syntax.Abs.HeadThis -> failure x + Language.EO.Phi.Rules.Syntax.Abs.HeadTermination -> failure x + +transObjectAction :: Language.EO.Phi.Rules.Syntax.Abs.ObjectAction -> Result +transObjectAction x = case x of + Language.EO.Phi.Rules.Syntax.Abs.ActionApplication bindings -> failure x + Language.EO.Phi.Rules.Syntax.Abs.ActionDispatch attribute -> failure x diff --git a/eo-phi-normalizer/src/Language/EO/Phi/Rules/Syntax/Test.hs b/eo-phi-normalizer/src/Language/EO/Phi/Rules/Syntax/Test.hs new file mode 100644 index 000000000..589caf722 --- /dev/null +++ b/eo-phi-normalizer/src/Language/EO/Phi/Rules/Syntax/Test.hs @@ -0,0 +1,76 @@ +-- File generated by the BNF Converter (bnfc 2.9.5). + +-- | Program to test parser. + +module Main where + +import Prelude + ( ($), (.) + , Either(..) + , Int, (>) + , String, (++), concat, unlines + , Show, show + , IO, (>>), (>>=), mapM_, putStrLn + , FilePath + , getContents, readFile + ) +import System.Environment ( getArgs ) +import System.Exit ( exitFailure ) +import Control.Monad ( when ) + +import Language.EO.Phi.Rules.Syntax.Abs () +import Language.EO.Phi.Rules.Syntax.Lex ( Token, mkPosToken ) +import Language.EO.Phi.Rules.Syntax.Par ( pProgram, myLexer ) +import Language.EO.Phi.Rules.Syntax.Print ( Print, printTree ) +import Language.EO.Phi.Rules.Syntax.Skel () + +type Err = Either String +type ParseFun a = [Token] -> Err a +type Verbosity = Int + +putStrV :: Verbosity -> String -> IO () +putStrV v s = when (v > 1) $ putStrLn s + +runFile :: (Print a, Show a) => Verbosity -> ParseFun a -> FilePath -> IO () +runFile v p f = putStrLn f >> readFile f >>= run v p + +run :: (Print a, Show a) => Verbosity -> ParseFun a -> String -> IO () +run v p s = + case p ts of + Left err -> do + putStrLn "\nParse Failed...\n" + putStrV v "Tokens:" + mapM_ (putStrV v . showPosToken . mkPosToken) ts + putStrLn err + exitFailure + Right tree -> do + putStrLn "\nParse Successful!" + showTree v tree + where + ts = myLexer s + showPosToken ((l,c),t) = concat [ show l, ":", show c, "\t", show t ] + +showTree :: (Show a, Print a) => Int -> a -> IO () +showTree v tree = do + putStrV v $ "\n[Abstract Syntax]\n\n" ++ show tree + putStrV v $ "\n[Linearized tree]\n\n" ++ printTree tree + +usage :: IO () +usage = do + putStrLn $ unlines + [ "usage: Call with one of the following argument combinations:" + , " --help Display this help message." + , " (no arguments) Parse stdin verbosely." + , " (files) Parse content of files verbosely." + , " -s (files) Silent mode. Parse content of files silently." + ] + +main :: IO () +main = do + args <- getArgs + case args of + ["--help"] -> usage + [] -> getContents >>= run 2 pProgram + "-s":fs -> mapM_ (runFile 0 pProgram) fs + fs -> mapM_ (runFile 2 pProgram) fs + diff --git a/eo-phi-normalizer/src/Language/EO/Phi/Rules/Yaml.hs b/eo-phi-normalizer/src/Language/EO/Phi/Rules/Yaml.hs new file mode 100644 index 000000000..835c48767 --- /dev/null +++ b/eo-phi-normalizer/src/Language/EO/Phi/Rules/Yaml.hs @@ -0,0 +1,92 @@ +{-# OPTIONS_GHC -Wno-orphans #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE DeriveAnyClass #-} +module Language.EO.Phi.Rules.Yaml where + +import GHC.Generics (Generic) +import Data.Aeson (FromJSON(..)) +import qualified Data.Yaml as Yaml +import Data.String (IsString(..)) +import qualified Language.EO.Phi.Rules.Syntax.Abs as Rules +import qualified Language.EO.Phi.Rules.Syntax.Par as Rules + +import qualified Language.EO.Phi.Rules.Common as Common + +instance IsString Rules.Object where + fromString = unsafeParseObject + +instance FromJSON Rules.Object where + parseJSON = fmap fromString . parseJSON + +instance FromJSON Rules.MetaId where + parseJSON = fmap Rules.MetaId . parseJSON + +-- | Parse a 'Object' or return a parsing error. +parseObject :: String -> Either String Rules.Object +parseObject input = Rules.pObject tokens + where + tokens = Rules.myLexer input + +-- | Parse a 'Object' from a 'String'. +-- May throw an 'error` if input has a syntactical or lexical errors. +unsafeParseObject :: String -> Rules.Object +unsafeParseObject input = + case parseObject input of + Left parseError -> error parseError + Right object -> object + + +data RuleSet = RuleSet + { title :: String + , rules :: [Rule] + } deriving (Generic, FromJSON, Show) + +data Rule = Rule + { name :: String + , description :: String + , pattern :: Rules.Object + , result :: Rules.Object + , when :: [Condition] + } deriving (Generic, FromJSON, Show) + +data Condition + = IsNF { nf :: [Rules.MetaId] } + deriving (Generic, FromJSON, Show) + +parseRuleSetFromFile :: FilePath -> IO RuleSet +parseRuleSetFromFile = Yaml.decodeFileThrow + +convertRule :: Rule -> Common.Rule +convertRule Rule{..} ctx obj = + [ obj' + | subst <- match pattern obj + , let obj' = applySubst subst result + ] + +-- input: ⟦ a ↦ ⟦ c ↦ ⟦ ⟧ ⟧, b ↦ ⟦ ⟧ ⟧.a + +-- pattern: ⟦ ?a ↦ ?n, ?B ⟧.?a +-- result: ?n(ρ ↦ ⟦ ?B ⟧) + +-- match pattern input (get substitution): +-- ?a = a +-- ?n = ⟦ c ↦ ⟦ ⟧ ⟧ +-- ?B = b ↦ ⟦ ⟧ + +-- actual result (after applying substitution): +-- ⟦ c ↦ ⟦ ⟧ ⟧(ρ ↦ ⟦ b ↦ ⟦ ⟧ ⟧) + +data Subst = Subst + { objectMetas :: [(MetaId, Phi.Object)] + , bindingsMetas :: [(MetaId, [Phi.Binding])] + , attributeMetas :: [(MetaId, Phi.Attribute)] + } + +emptySubst :: Subst +emptySubst = Subst [] [] [] + +mergeSubst :: Subst -> Subst -> Subst + +match :: Rules.Object -> Phi.Object -> Subst +match m@MetaId{} obj = Subst { objectMetas = [(m, obj)], bindingsMetas = [], attributeMetas = [] } +match