Tenga en cuenta que, posteriormente a la publicación de esta pregunta, pude obtener una solución yo mismo. Vea el final de esta pregunta para mi respuesta final.Analizando texto con datos opcionales al final
Estoy trabajando en un pequeño analizador en el momento de org-mode documentos, y en estos documentos partidas puedo tener un título, y, opcionalmente, puede consistir en una lista de etiquetas en el de la partida a:
* Heading :foo:bar:baz:
Tengo dificultades para escribir un analizador para esto, sin embargo. Lo siguiente es lo que estoy trabajando con, por ahora:
import Control.Applicative
import Text.ParserCombinators.Parsec
data Node = Node String [String]
deriving (Show)
myTest = parse node "" "Some text here :tags:here:"
node = Node <$> (many1 anyChar) <*> tags
tags = (char ':') >> (sepEndBy1 (many1 alphaNum) (char ':'))
<?> "Tag list"
Mientras mis trabajos simples analizador tags
, que no funciona en el contexto de node
porque todos los caracteres se utilizan hasta analizar el título del epígrafe (many1 anyChar
). Además, no puedo cambiar este analizador para usar noneOf ":"
porque :
es válido en el título. De hecho, solo es especial si está en un taglist, al final de la línea.
¿Alguna idea de cómo puedo analizar estos datos opcionales?
Como un lado, este es mi primer proyecto real de Haskell, así que si Parsec no es ni siquiera la herramienta adecuada para el trabajo, siéntase libre de señalarlo y sugerir otras opciones.
Bien, ahora tengo una solución completa, pero es necesario refactorizarla. Las siguientes obras:
import Control.Applicative hiding (many, optional, (<|>))
import Control.Monad
import Data.Char (isSpace)
import Text.ParserCombinators.Parsec
data Node = Node { level :: Int, keyword :: Maybe String, heading :: String, tags :: Maybe [String] }
deriving (Show)
parseNode = Node <$> level <*> (optionMaybe keyword) <*> name <*> (optionMaybe tags)
where level = length <$> many1 (char '*') <* space
keyword = (try (many1 upper <* space))
name = noneOf "\n" `manyTill` (eof <|> (lookAhead (try (tags *> eof))))
tags = char ':' *> many1 alphaNum `sepEndBy1` char ':'
myTest = parse parseNode "org-mode" "** Some : text here :tags: JUST KIDDING :tags:here:"
myTest2 = parse parseNode "org-mode" "* TODO Just a node"
¿Qué hay de analizar primero la cabecera de un iluminado y de ordenación de los datos en su estructura? – fuz
Hola, no sé lo que estoy "encendida", pero todavía no veo cómo puedo analizar el encabezado e ignorar las etiquetas, sin consumir la sección de etiquetas en mi analizador – ocharles
Hola @ocharles , ¿está realmente presente el analizador de modo orgánico resultante? ¿Está compartiendo el código? Empecé a profundizar un poco en Haskell, y la combinación de este aprendizaje con el cambio de modo orgánico es de alguna manera un pensamiento agradable. Saludos cordiales, –