<commit_before>{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}
module Data.Kicad.SExpr.Parse
( parse
)
where
import Text.ParserCombinators.Parsec hiding (spaces, parse)
import qualified Text.ParserCombinators.Parsec as Parsec (parse)
import Text.ParserCombinators.Parsec.Number
import Text.Parsec.Char (endOfLine)
import Control.Monad

import Data.Kicad.SExpr.SExpr
import Data.Kicad.SExpr.Write (writeKeyword)

{-| Parse a 'String' as a 'SExpr' or return an error. -}
parse :: String -> Either String SExpr
parse input = case Parsec.parse parseListOrComment "SExpr" input of
    Left err -> Left $ "Parse Error: " ++ show err
    Right val -> Right val


parseListOrComment :: Parser SExpr
parseListOrComment = do
    spaces
    skipMany parseComment
    spaces
    s <- parseList
    return s


parseComment :: Parser String
parseComment = do
    char '#'
    s <- many (noneOf "\r\n")
    endOfLine
    return s


parseList :: Parser SExpr
parseList = do
    char '('
    spaces
    first <- parseKeyword
    spaces
    rest <- let parseRest = try parseAtom `sepEndBy` spaces in case first of
        AtomKey KeyFpText -> do t <- parseString
                                  <?> "string designating type e.g. 'user'"
                                spaces1
                                s <- parseString
                                spaces
                                r <- parseRest
                                return (t:s:r)
        AtomKey KeyModule -> do t <- parseString
                                spaces
                                r <- parseRest
                                return (t:r)
        AtomKey KeyTedit  -> do s <- parseString
                                spaces
                                return [s]
        AtomKey KeyDescr  -> do s <- parseString
                                spaces
                                return [s]
        AtomKey KeyTags   -> do s <- parseString
                                spaces
                                return [s]
        AtomKey KeyPad    -> do n <- parseString
                                spaces1
                                t <- parseString
                                  <?> "string designating type e.g. 'smd'"
                                spaces1
                                s <- parseString
                                spaces
                                r <- parseRest
                                return (n:t:s:r)
        _                 -> parseRest
    spaces
    char ')'
    spaces
    return $ List (first:rest)

parseAtom :: Parser SExpr
parseAtom =  try parseDouble
         <|> try parseString
         <|> try parseList<commit_msg>Add support for (ignoring) comments within expressions<commit_after>{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}
module Data.Kicad.SExpr.Parse
( parse
)
where
import Text.ParserCombinators.Parsec hiding (spaces, parse)
import qualified Text.ParserCombinators.Parsec as Parsec (parse)
import Text.ParserCombinators.Parsec.Number
import Text.Parsec.Char (endOfLine)
import Control.Monad

import Data.Kicad.SExpr.SExpr
import Data.Kicad.SExpr.Write (writeKeyword)

{-| Parse a 'String' as a 'SExpr' or return an error. -}
parse :: String -> Either String SExpr
parse input = case Parsec.parse parseListOrComment "SExpr" input of
    Left err -> Left $ "Parse Error: " ++ show err
    Right val -> Right val


parseListOrComment :: Parser SExpr
parseListOrComment = do
    spaces
    skipMany parseComment
    spaces
    s <- parseList
    return s


parseComment :: Parser String
parseComment = do
    char '#'
    s <- many (noneOf "\r\n")
    endOfLine
    return s


parseList :: Parser SExpr
parseList = do
    char '('
    spaces
    first <- parseKeyword
    spaces
    rest <- let parseRest = try parseAtom `sepEndBy` spaces in case first of
        AtomKey KeyFpText -> do t <- parseString
                                  <?> "string designating type e.g. 'user'"
                                spaces1
                                s <- parseString
                                spaces
                                r <- parseRest
                                return (t:s:r)
        AtomKey KeyModule -> do t <- parseString
                                spaces
                                r <- parseRest
                                return (t:r)
        AtomKey KeyTedit  -> do s <- parseString
                                spaces
                                return [s]
        AtomKey KeyDescr  -> do s <- parseString
                                spaces
                                return [s]
        AtomKey KeyTags   -> do s <- parseString
                                spaces
                                return [s]
        AtomKey KeyPad    -> do n <- parseString
                                spaces1
                                t <- parseString
                                  <?> "string designating type e.g. 'smd'"
                                spaces1
                                s <- parseString
                                spaces
                                r <- parseRest
                                return (n:t:s:r)
        _                 -> parseRest
    spaces
    char ')'
    spaces
    return $ List (first:rest)

parseAtom :: Parser SExpr
parseAtom =  try parseDouble
         <|> try parseString
         <|> try parseListOrComment
{'fraction_non_alphanumeric': 0.07449127906976744, 'fraction_numerical': 0.0010901162790697674, 'mean_word_length': 1.190608834062873, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3187026', 'n_tokens_mistral': 1482, 'n_tokens_neox': 1393, 'n_words': 411}