Extract properties block parser to file
This commit is contained in:
59
src/org/org_parser_properties_block.nim
Normal file
59
src/org/org_parser_properties_block.nim
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import std/sugar
|
||||||
|
import std/strformat
|
||||||
|
import std/collections/sequtils
|
||||||
|
import std/strutils
|
||||||
|
import results
|
||||||
|
import fusion/matching
|
||||||
|
|
||||||
|
import ../utils/fp
|
||||||
|
import ../parser/parser
|
||||||
|
import ../parser/utils
|
||||||
|
|
||||||
|
{.experimental: "caseStmtMacros".}
|
||||||
|
|
||||||
|
|
||||||
|
let propertiesKeyParser* = ignore(ch(':')) + anyUntil(choice(@[str(": "), newline]))
|
||||||
|
let propertiesValueParser* = ignore(str(": ")) + anyUntil(newline) + ignore(newline)
|
||||||
|
|
||||||
|
let propertiesParser* = proc(parser: Parser): ParserResult {.closure.} =
|
||||||
|
let keyTokenParser = parser
|
||||||
|
.propertiesKeyParser()
|
||||||
|
.flatMap(flattenParserTokens)
|
||||||
|
|
||||||
|
let valueTokenParser = keyTokenParser
|
||||||
|
.map(emptyTokens)
|
||||||
|
.flatMap(propertiesValueParser)
|
||||||
|
.flatMap(flattenParserTokens)
|
||||||
|
|
||||||
|
case (keyTokenParser, valueTokenParser):
|
||||||
|
of (Some(@key), Some(@value)):
|
||||||
|
ok(Parser(
|
||||||
|
state: value.state,
|
||||||
|
tokens: @[
|
||||||
|
key.tokens[0],
|
||||||
|
value.tokens[0],
|
||||||
|
]
|
||||||
|
))
|
||||||
|
else: valueTokenParser
|
||||||
|
|
||||||
|
let propertiesStartParser* = str(":PROPERTIES_START:") + newline
|
||||||
|
let propertiesEndParser* = str(":PROPERTIES_END:") + newline
|
||||||
|
|
||||||
|
let parseProperties* = @[
|
||||||
|
ignore(propertiesStartParser),
|
||||||
|
manyUntil(
|
||||||
|
propertiesParser,
|
||||||
|
propertiesEndParser,
|
||||||
|
),
|
||||||
|
ignore(propertiesEndParser),
|
||||||
|
]
|
||||||
|
|
||||||
|
when isMainModule:
|
||||||
|
let example = initParserResult(""":PROPERTIES:
|
||||||
|
:PROP_NAME: Value
|
||||||
|
:PROP_NAME: Value
|
||||||
|
:PROP_NAME: Value
|
||||||
|
:PROP_NAME: Value
|
||||||
|
:PROPERTIES_END:""").parseSeq(parseProperties)
|
||||||
|
|
||||||
|
echo example
|
||||||
@@ -3,30 +3,13 @@ import std/strformat
|
|||||||
import std/collections/sequtils
|
import std/collections/sequtils
|
||||||
import std/strutils
|
import std/strutils
|
||||||
import parser/parser
|
import parser/parser
|
||||||
|
import parser/utils
|
||||||
import results
|
import results
|
||||||
import utils/fp
|
import utils/fp
|
||||||
import fusion/matching
|
import fusion/matching
|
||||||
|
|
||||||
{.experimental: "caseStmtMacros".}
|
{.experimental: "caseStmtMacros".}
|
||||||
|
|
||||||
type StringBuilderT = string
|
|
||||||
type StringBuilder = Builder[StringBuilderT]
|
|
||||||
type StringBuilderResult = BuilderResult[StringBuilderT]
|
|
||||||
proc stringConcat(typeInfo: StringBuilderT):
|
|
||||||
(seq[ParserToken], seq[StringBuilderT]) -> seq[StringBuilderT] =
|
|
||||||
|
|
||||||
return proc(xs: seq[ParserToken], ys: seq[StringBuilderT]): seq[StringBuilderT] =
|
|
||||||
return ys & xs.foldl(a & b.tokenStringValue(), typeInfo)
|
|
||||||
|
|
||||||
|
|
||||||
proc initStringBuilder(str: string): StringBuilderResult =
|
|
||||||
StringBuilderResult
|
|
||||||
.ok(StringBuilder((
|
|
||||||
parser: initParser(str),
|
|
||||||
tree: newSeq[StringBuilderT](),
|
|
||||||
)))
|
|
||||||
|
|
||||||
when isMainModule:
|
|
||||||
let parseHeadingStars = @[
|
let parseHeadingStars = @[
|
||||||
manyUntil(ch('*'), ch(' ')),
|
manyUntil(ch('*'), ch(' ')),
|
||||||
ignore(ch(' '))
|
ignore(ch(' '))
|
||||||
@@ -41,56 +24,12 @@ when isMainModule:
|
|||||||
let parseTodoKeyword = todoKeywords.createTodoKeywordParser()
|
let parseTodoKeyword = todoKeywords.createTodoKeywordParser()
|
||||||
let parseDoneKeyword = doneKeywords.createTodoKeywordParser()
|
let parseDoneKeyword = doneKeywords.createTodoKeywordParser()
|
||||||
|
|
||||||
let propertiesKeyParser = ignore(ch(':')) + anyUntil(choice(@[str(": "), newline]))
|
|
||||||
let propertiesValueParser = ignore(str(": ")) + anyUntil(newline) + ignore(newline)
|
|
||||||
let propertiesParser = proc(parser: Parser): ParserResult {.closure.} =
|
|
||||||
let keyTokenParser = parser
|
|
||||||
.propertiesKeyParser()
|
|
||||||
.flatMap(flattenParserTokens)
|
|
||||||
|
|
||||||
|
|
||||||
let valueTokenParser = keyTokenParser
|
|
||||||
.map(emptyTokens)
|
|
||||||
.flatMap(propertiesValueParser)
|
|
||||||
.flatMap(flattenParserTokens)
|
|
||||||
|
|
||||||
case (keyTokenParser, valueTokenParser):
|
|
||||||
of (Some(@key), Some(@value)):
|
|
||||||
ok(Parser(
|
|
||||||
state: value.state,
|
|
||||||
tokens: @[
|
|
||||||
key.tokens[0],
|
|
||||||
value.tokens[0],
|
|
||||||
]
|
|
||||||
))
|
|
||||||
else: valueTokenParser
|
|
||||||
|
|
||||||
let propertiesStartParser = str(":PROPERTIES_START:") + newline
|
|
||||||
let propertiesEndParser = str(":PROPERTIES_END:") + newline
|
|
||||||
|
|
||||||
let parseProperties = @[
|
|
||||||
ignore(propertiesStartParser),
|
|
||||||
manyUntil(
|
|
||||||
propertiesParser,
|
|
||||||
propertiesEndParser,
|
|
||||||
),
|
|
||||||
ignore(propertiesEndParser),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
echo initParserResult(""":PROPERTIES:
|
|
||||||
:PROP_NAME: Value
|
|
||||||
:PROP_NAME: Value
|
|
||||||
:PROP_NAME: Value
|
|
||||||
:PROP_NAME: Value
|
|
||||||
:PROPERTIES_END:
|
|
||||||
""").parseSeq(parseProperties)
|
|
||||||
|
|
||||||
let parseHeadingText = @[
|
let parseHeadingText = @[
|
||||||
anyUntil(newline),
|
anyUntil(newline),
|
||||||
ignore(newline),
|
ignore(newline),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
when isMainModule:
|
||||||
let sampleBuilder = StringBuilderResult
|
let sampleBuilder = StringBuilderResult
|
||||||
.ok(StringBuilder((
|
.ok(StringBuilder((
|
||||||
parser: initParser("""**** TODO Some stars
|
parser: initParser("""**** TODO Some stars
|
||||||
@@ -118,4 +57,4 @@ when isMainModule:
|
|||||||
xs => "Parser Succesfull:\n" & xs.join("\n"),
|
xs => "Parser Succesfull:\n" & xs.join("\n"),
|
||||||
)
|
)
|
||||||
|
|
||||||
# echo sampleBuilder
|
echo sampleBuilder
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ type
|
|||||||
# keyValuePairValue*: parserTokenKeyValuePairValueT
|
# keyValuePairValue*: parserTokenKeyValuePairValueT
|
||||||
|
|
||||||
Parser* = ref object
|
Parser* = ref object
|
||||||
state: ParserState
|
state*: ParserState
|
||||||
tokens: seq[ParserToken]
|
tokens*: seq[ParserToken]
|
||||||
|
|
||||||
ParseErrorKind = enum
|
ParseErrorKind = enum
|
||||||
choiceMismatchErr
|
choiceMismatchErr
|
||||||
@@ -238,6 +238,26 @@ func ignore*(parserFn: Parser -> ParserResult): (Parser -> ParserResult) {.inlin
|
|||||||
tokens: parser.tokens,
|
tokens: parser.tokens,
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
|
func flattenParserTokens*(parser: Parser): ParserResult =
|
||||||
|
return ParserResult.ok(
|
||||||
|
Parser(
|
||||||
|
state: parser.state,
|
||||||
|
tokens: @[
|
||||||
|
ParserToken(
|
||||||
|
kind: parserTokenString,
|
||||||
|
stringValue: parser.tokens.foldl(a & b.tokenStringValue(), "")
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
func emptyTokens*(parser: Parser): Parser =
|
||||||
|
Parser(
|
||||||
|
state: parser.state,
|
||||||
|
tokens: newSeq[ParserToken](),
|
||||||
|
)
|
||||||
|
|
||||||
func optional*(parserFn: Parser -> ParserResult): (Parser -> ParserResult) {.inline.} =
|
func optional*(parserFn: Parser -> ParserResult): (Parser -> ParserResult) {.inline.} =
|
||||||
## Parse characters and ignore failure
|
## Parse characters and ignore failure
|
||||||
return proc(parser: Parser): ParserResult =
|
return proc(parser: Parser): ParserResult =
|
||||||
@@ -293,8 +313,8 @@ proc `+`*(parserFnA: Parser -> ParserResult, parserFnB: Parser -> ParserResult):
|
|||||||
|
|
||||||
|
|
||||||
let newlineParser = choice(@[
|
let newlineParser = choice(@[
|
||||||
|
ch(NewLines),
|
||||||
endOfStream,
|
endOfStream,
|
||||||
ch(NewLines)
|
|
||||||
])
|
])
|
||||||
proc newline*(parser: Parser): ParserResult = newlineParser(parser)
|
proc newline*(parser: Parser): ParserResult = newlineParser(parser)
|
||||||
|
|
||||||
|
|||||||
21
src/parser/utils.nim
Normal file
21
src/parser/utils.nim
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import std/sugar
|
||||||
|
import std/collections/sequtils
|
||||||
|
import ./parser
|
||||||
|
import results
|
||||||
|
|
||||||
|
type StringBuilderT* = string
|
||||||
|
type StringBuilder* = Builder[StringBuilderT]
|
||||||
|
type StringBuilderResult* = BuilderResult[StringBuilderT]
|
||||||
|
|
||||||
|
proc stringConcat*(typeInfo: StringBuilderT):
|
||||||
|
(seq[ParserToken], seq[StringBuilderT]) -> seq[StringBuilderT] =
|
||||||
|
|
||||||
|
return proc(xs: seq[ParserToken], ys: seq[StringBuilderT]): seq[StringBuilderT] =
|
||||||
|
return ys & xs.foldl(a & b.tokenStringValue(), typeInfo)
|
||||||
|
|
||||||
|
proc initStringBuilder*(str: string): StringBuilderResult =
|
||||||
|
StringBuilderResult
|
||||||
|
.ok(StringBuilder((
|
||||||
|
parser: initParser(str),
|
||||||
|
tree: newSeq[StringBuilderT](),
|
||||||
|
)))
|
||||||
@@ -1,5 +1,9 @@
|
|||||||
import std/sugar
|
import std/sugar
|
||||||
import fp/maybe
|
import fp/maybe
|
||||||
|
import results
|
||||||
|
|
||||||
|
template isSome*(self: Result): bool = self.isOk()
|
||||||
|
template isNone*(self: Result): bool = self.isErr()
|
||||||
|
|
||||||
proc findMaybe*[T](xs: seq[T], fn: T -> bool): Maybe[T] =
|
proc findMaybe*[T](xs: seq[T], fn: T -> bool): Maybe[T] =
|
||||||
for x in xs:
|
for x in xs:
|
||||||
|
|||||||
Reference in New Issue
Block a user