summaryrefslogtreecommitdiff
path: root/src/Thue/Parser.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Thue/Parser.hs')
-rw-r--r--src/Thue/Parser.hs84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/Thue/Parser.hs b/src/Thue/Parser.hs
new file mode 100644
index 0000000..2ee41ae
--- /dev/null
+++ b/src/Thue/Parser.hs
@@ -0,0 +1,84 @@
+module Thue.Parser (
+ ThueProgram(..),
+ ThueRule(..),
+ ThueState,
+
+ parseThue
+ ) where
+
+import Control.Applicative( some )
+import Text.ParserCombinators.Parsec
+
+
+
+data ThueProgram = ThueProgram { thueRules :: [ThueRule]
+ , thueInitialState :: ThueState }
+ deriving (Show, Eq)
+
+
+data ThueRule = ThueRule { original :: ThueState
+ , replacement :: ThueState }
+ deriving (Show, Eq)
+
+
+type ThueState = String
+
+
+
+
+parseThue :: String -> Either ParseError ThueProgram
+parseThue = parse thue "error"
+
+
+
+
+thue = do
+ rs <- many rule
+ separatorLine
+ i <- initialState
+ eof
+ return (ThueProgram rs i)
+
+
+rule = do
+ o <- ruleState
+ separator
+ r <- state
+ eol
+ return (ThueRule o r)
+
+
+separatorLine = whiteSpace >> separator >> whiteSpace >> eol
+separator = string "::="
+ <?> "rule separator"
+
+
+initialState = do
+ s <- state `sepEndBy` eol
+ return (concat s)
+
+
+ruleState = some ruleStateChar
+
+
+ruleStateChar = noneOf "\n\r:"
+ <|> try (char ':' >> notFollowedBy (string ":=") >> return ':')
+ <?> "state character"
+
+
+state = many stateChar
+
+
+stateChar = noneOf "\n\r"
+ <?> "state character"
+
+
+whiteSpace = many (oneOf "\t ")
+
+
+eol = try (string "\r\n")
+ <|> try (string "\n\r")
+ <|> try (string "\r")
+ <|> try (string "\n")
+ <?> "end of line"
+