Skip to content

Instantly share code, notes, and snippets.

@kazuki0824
Created September 20, 2023 15:00
Show Gist options
  • Save kazuki0824/54036ec6445ce3b2eb00f822929d381b to your computer and use it in GitHub Desktop.
Save kazuki0824/54036ec6445ce3b2eb00f822929d381b to your computer and use it in GitHub Desktop.
PyParsingとChatGPTを用いたパーサーコンビネータ入門
"""
与えたプロンプト
論理式のパーサーをpyparsingで作りたい。要件は以下の通り。
1. 各項目名はダブルクォーテーションで囲まれる。例 "anthurium"
2. ダブルクォーテーション自体を含む場合、それは2つのダブルクォーテーションとして表現される。例 "forget""me ""not"
3. 各項目の手前に!を置くことで「否定」を表現できる。例 !"rose"
4. 各項目を&演算子で繋げることができる。つまり"anthurium"&!"dandelion"|"rose"
5. 丸いカッコ()を用いて演算順序の表現ができるようにする。例 !"anthurium" & ((!"dandelion"| "rose") & "sunflower")
"""
from pyparsing import QuotedString, Literal, Forward, Group, infixNotation, opAssoc
def parser(body_format=QuotedString('"', escQuote='""')):
"""
Constructs a parser for expressions that may include logical operators
('&', '|') and negations ('!').
:param body_format: The format for quoted strings in the expressions. Defaults to double-quoted strings.
:type body_format: pyparsing.ParserElement
:return: A parser for the defined expressions.
:rtype: pyparsing.ParserElement
Example:
Given an input string like '"A" & "B" | ! "C"', this parser will construct a parse tree
with logical AND, OR, and NOT operators.
"""
# 3. 否定を表現する!
not_op = Literal('!')('not')
body_format = (not_op + body_format) | body_format
# 5. 丸いカッコ()を用いて演算順序の表現
expr = Forward()
# 4. &演算子と|演算子
and_op = Literal('&')('and')
or_op = Literal('|')('or')
expr << Group(body_format + (and_op + expr | or_op + expr) | body_format)
# 演算順序の定義
return infixNotation(expr, [
(and_op, 2, opAssoc.LEFT),
(or_op, 2, opAssoc.LEFT),
(not_op, 1, opAssoc.RIGHT),
])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment