ELMによる聖書参照の解析
これは元々はdeanmontgomery.com .
この記事では、ELMでシンプルなパーサーを書く方法について簡単に紹介します.
私たちが解析されることは聖書の参照です:聖書の参照は、1つはすぐに聖書のテキスト内の特定の詩や範囲の詩を見てみましょう速記です.
簡単ですね.
聖書の参照を開始位置と終了位置に分割することができます.それぞれの場所は、本、章と詩から成ります.
それで、リファレンスは似ているかもしれません
しかし、リファレンスはこれらのいずれかのように見えます. さらに、聖書のいくつかの本は、単一の章(例えばジュード)を持っている、とコンベンションによって、章番号は参照から削除されます.So
パーサを書くとき、これらのケースの全てを処理することを目指します.
elm/parser スーパーニース解析ライブラリは、エルムの作成者とメンテナによって書かれています.私はそれの詳細にここに行かないtutorial and conference talk あなたがより深く掘りたいならば.
聖書のリファレンスを2つのステップで解析します. 文字列を構文リストに解析する 次に、有効な参照をチェックする文のリストを検証します
聖書の参照には、スペース、コロン、誇らしげ、本の名前と数を持つことができます.
現在、我々は声明のリストを持っています
まず定義する
この検証のすべてをパーサー内で動かすことが可能であり、すべての作業を1ステップで行うことが可能であるべきだと思います.
この記事では、ELMでパーサーを作成する方法を示しています.うまくいけば、これはパーサーの構築を開始するのに役立ちます.
パーサーをビルドするのを気にしないでください、そして、ちょうどあなたのためにこれをするためにELMパッケージが欲しいならば、チェックしてくださいmonty5811/elm-bible それはパーサー、良いフォーマットとコンパクトなエンコーダ/デコーダを提供します.
エルムバイブル
文字列から参照を解析する うまく文字列への参照をフォーマットする 参照を並べ替え/比較/記憶のためにコード化された表現に変えてください 以下の参照書式を解析できます: 創世記1 創世記1章1 創世記1章1 - 20 創世記20章2時24分 ジェネシス1 - 5 エクソダス5 エクソダス5 : 20 エクソダス5 エクソダス5 : 20
( fromstring "gen 1 : 1 "ξ> result . map format )
=== "ジェネシス1 : 1 "
( fromstring "gen 1 : 1 - rev 5 ")マップ形式
= = "創世記1 : 1 -黙示録5 : 14 "
( fromstring "gen 1 : 1 - rev 5 ")マップエンコード
=== OK { start = 1001001 , end = 66005014
寄付歓迎open an issue 始める.
View on GitHub
この記事では、ELMでシンプルなパーサーを書く方法について簡単に紹介します.
私たちが解析されることは聖書の参照です:聖書の参照は、1つはすぐに聖書のテキスト内の特定の詩や範囲の詩を見てみましょう速記です.
簡単ですね.
どのようなリファレンスのようですか?
聖書の参照を開始位置と終了位置に分割することができます.それぞれの場所は、本、章と詩から成ります.
それで、リファレンスは似ているかもしれません
Genesis 1:1 - Exodus 2:1
それは創世記の第1章の最初の節から始まり、第2章の第1章で終わりを告げます.しかし、リファレンスはこれらのいずれかのように見えます.
Genesis 1
- 全体の章Genesis 1:1
- 一節Genesis 1:1-20
Genesis 1:20-2:24
Genesis 1-5
- 複数の章Genesis 1 - Exodus 5
Genesis 1:1 - Exodus 5:20
Genesis 1:1 - Exodus 5
Genesis 1 - Exodus 5:20
Jude 2
ジュードの最初の(そして唯一の)章の2番目の節は、すべてのジュード第2章です.パーサを書くとき、これらのケースの全てを処理することを目指します.
ELMで構文解析を行うには?
elm/parser スーパーニース解析ライブラリは、エルムの作成者とメンテナによって書かれています.私はそれの詳細にここに行かないtutorial and conference talk あなたがより深く掘りたいならば.
聖書のリファレンスを2つのステップで解析します.
文のリストを取得する
聖書の参照には、スペース、コロン、誇らしげ、本の名前と数を持つことができます.
type Statement
= BookName Book
| Num Int
| Dash
| Colon
とパーサが文字列をリストのリストに変換する{-| A `List Statement` parser. We use `P.loop` to consume the whole string
-}
parser : P.Parser (List Statement)
parser =
P.loop [] statementsHelp
statementsHelp : List Statement -> P.Parser (P.Step (List Statement) (List Statement))
statementsHelp revStmts =
P.oneOf
[ P.succeed (\stmt -> P.Loop (stmt :: revStmts))
|. P.spaces
|= statement
|. P.spaces
, P.succeed ()
|> P.map (\_ -> P.Done (List.reverse revStmts))
]
{-| A `Statement` parser
-}
statement : P.Parser Statement
statement =
P.oneOf
[ P.map BookName (P.oneOf bookTokensList)
, P.map (\_ -> Dash) (P.symbol "-")
, P.map (\_ -> Colon) (P.symbol ":")
, P.map Num P.int
]
このパーサを使用すると、文字列をList Statement
:parse : String -> Result String (List Statement)
parse str =
P.run parser str
文のリストの妥当性検査
現在、我々は声明のリストを持っています
[Book Genesis, Colon, Num 1]
or [Book John, Colon, Num 2, Dash, Num 2]
, しかし、我々には声明の有効なコレクションがあることを保証する何もありません.例えば、私たちは[Colon, Colon, Colon]
これは明らかに有効ではない.[Book Genesis, Num 52]
これは有効ですが、創世記には50冊しかありません.まず定義する
Reference
種類:type alias Reference =
{ startBook : Book
, startChapter : Int
, startVerse : Int
, endBook : Book
, endChapter : Int
, endVerse : Int
}
と関数processStatements : List Statement -> Result String Reference
これはステートメントのリストを有効にします.この機能は、利用可能なすべての可能な形式を説明し、単一の章の書籍を扱うためにかなり大きいですが、関数は本質的にcase
文processStatementsHelp : List Statement -> Result String Reference
processStatementsHelp stmts =
case stmts of
-- Gen
[ BookName bk ] ->
reference
bk
1
1
bk
(numChapters bk)
(numVerses bk (numChapters bk))
-- Gen 1
[ BookName bk, Num ch ] ->
if numChapters bk == 1 then
reference
bk
1
ch
bk
1
ch
else
reference
bk
ch
1
bk
ch
(numVerses bk 1)
-- truncated for brevity (full function can be seen: https://github.com/monty5811/elm-bible/blob/2.0.0/src/Internal/Parser.elm#L38-L243)
-- Genesis - Revelation
[ BookName startBk, Dash, BookName endBk ] ->
reference
startBk
1
1
endBk
(numChapters endBk)
(numVerses endBk (numChapters endBk))
[] ->
Err "No reference found"
_ ->
Err <| "No valid reference found"
今、我々はReference
これには、スタートブック、スタート章、開始節、終了章、終了節が含まれていますが、これらのすべてが順番にチェックされていません(例えば、参照が開始される前には参照できません).validateRef : Reference -> Result String Reference
validateRef ref =
validateBookOrder ref
|> Result.andThen validateChapterOrder
|> Result.andThen validateVerseOrder
|> Result.andThen validateChapterBounds
|> Result.andThen validateVerseBounds
-- see each validate function here: https://github.com/monty5811/elm-bible/blob/2.0.0/src/Internal/Parser.elm#L363
ついに!我々は、検証聖書リファレンスがあります!この検証のすべてをパーサー内で動かすことが可能であり、すべての作業を1ステップで行うことが可能であるべきだと思います.
結論
この記事では、ELMでパーサーを作成する方法を示しています.うまくいけば、これはパーサーの構築を開始するのに役立ちます.
パーサーをビルドするのを気にしないでください、そして、ちょうどあなたのためにこれをするためにELMパッケージが欲しいならば、チェックしてくださいmonty5811/elm-bible それはパーサー、良いフォーマットとコンパクトなエンコーダ/デコーダを提供します.
モンティ5811 / エルムバイブル
エルムバイブル
ELMで聖書参照を解析して、フォーマットしてください.
機能
例
( fromstring "gen 1 : 1 "ξ> result . map format )
=== "ジェネシス1 : 1 "
( fromstring "gen 1 : 1 - rev 5 ")マップ形式
= = "創世記1 : 1 -黙示録5 : 14 "
( fromstring "gen 1 : 1 - rev 5 ")マップエンコード
=== OK { start = 1001001 , end = 66005014
貢献
寄付歓迎open an issue 始める.
View on GitHub
Reference
この問題について(ELMによる聖書参照の解析), 我々は、より多くの情報をここで見つけました https://dev.to/monty5811/parsing-bible-references-with-elm-3029テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol