【问题标题】:Common Lisp: A good way to represent grammar rules?Common Lisp:表示语法规则的好方法?
【发布时间】:2016-07-11 09:58:18
【问题描述】:

这是一个 Common Lisp 数据表示问题。

什么是表示语法的好方法?我所说的“好”是指简单、易于理解的表示,并且我可以对表示进行操作而不会大惊小怪。表示不必特别有效;其他属性(简单、可理解、可处理)对我来说更重要。

这是一个示例语法:

Session → Facts Question
Session → ( Session ) Session
Facts → Fact Facts
Facts → ε
Fact → ! STRING
Question → ? STRING

表示应该允许对表示进行操作的代码容易地区分终端符号和非终端符号。

非终结符:Session, Facts, Fact, Question

终端符号:(, ), ε, !, ?

这个特定的语法使用括号符号,这与 Common Lisp 对括号符号的使用相冲突。有什么好的方法来处理?

我希望我的代码能够识别空字符串的符号 ε。什么是表示空字符串符号ε的好方法?

我希望我的代码能够区分语法规则的左侧和右侧。

以下是我想对表示执行的一些常见操作。

考虑这条规则:

A → u1u2...un

操作:我想获取语法规则右侧的第一个符号。然后我想知道:它是终端符号吗?是ε符号吗?如果它是一个非终结符号,那么我想得到它的语法规则。

【问题讨论】:

  • 我在很久以前为 uni 做过类似的事情,你可能会觉得这些很有趣:backtracking parser, recursive descent LL(1), LALR(1)
  • 谢谢!因此,您将语法表示为关联列表。 a-list 的 key 代表语法规则的 LHS,key 的 value 代表 RHS。终端符号由字符串表示,非终端符号由原子表示。那是对的吗?事后看来,您对自己的代表感到满意吗?如果你要重新做,你会做不同的事情吗?你是如何表示空符号的?插入符号表示什么,例如 E^
  • E^ 中的插入符号仅代表E'。回想起来,我应该使用E*,因为星号似乎是 Lisp 领域中常用的修饰符。这三个解析器我不能给你太多评价,因为我从来没有在愤怒中使用过它们,这只是为了自学,同时在大学学习各种解析器算法。

标签: common-lisp grammar context-free-grammar representation


【解决方案1】:

GRAIL(Lisp 中的语法)

我从第二个链接中包含 GRAIL 的 BNF,以防它过期:

<grail-list>  ::= "'(" {<grail-rule>} ")"
<grail-rule>  ::= <assignment> | <alternation>
<assignment>  ::= "(" <type> " ::= " <s-exp> ")"
<alternation> ::= "(" <type> " ::= " <type> {<type>} ")"
<s-exp>       ::= <symbol> | <nonterminal> | "(" {<s-exp>} ")"
<type>        ::= "#(" <type-name> ")"
<nonterminal> ::= "#(" {<arg-name> " "} <type-name> ")"
<type-name>   ::= <symbol>
<arg-name>    ::= <symbol>

DCG 格式(定句语法)

Paradigms of Artificial Intelligence Programming 中有一个确定子句语法的实现。从技术上讲,它是 Prolog,但在本书中都是以 Lisp 实现的。

希望这会有所帮助!

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多