- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试利用 JavaScript 和 PEG.JS 将 lambda 演算项解析为 AST。语法相当简单:
/*****************************************************************
t ::=
x variable
λx.t abstraction
t t application
*****************************************************************/
我从中编码出了 PEG:
TERM "term"
= ABSTRACTION
/ APPLICATION
/ VARIABLE
APPLICATION "application"
/*****************************************************************
application ::= t t
*****************************************************************/
= APPLICATION_W_PARENS
/ APPLICATION_WO_PARENS
ABSTRACTION "abstraction"
/*****************************************************************
abstraction ::= λx.t
*****************************************************************/
= ABSTRACTION_W_PARENS
/ ABSTRACTION_WO_PARENS
VARIABLE "variable"
/*****************************************************************
variable ::= x
*****************************************************************/
= x:CHARACTER
{
return Variable(location(), x)
}
//////////////////////////////////////////////////////////////////////
// Application
//////////////////////////////////////////////////////////////////////
ABSTRACTION_OR_VARIABLE
//////////////////////////////////////////////////////////////////
// "Left recursive grammar" workaround "term term" enters a loop
// assuming the left side cannot match Application
// remediates the left recursion issue
//////////////////////////////////////////////////////////////////
= ABSTRACTION / VARIABLE
APPLICATION_W_PARENS
/*****************************************************************
'(' -> Abstraction | Variable -> Term -> ')'
*****************************************************************/
= L_PARENS lhs:ABSTRACTION_OR_VARIABLE rhs:TERM R_PARENS
{
return Application(location(), lhs, rhs, true)
}
APPLICATION_WO_PARENS
/*****************************************************************
Abstraction | Variable -> Term
*****************************************************************/
= lhs:ABSTRACTION_OR_VARIABLE rhs:TERM
{
return Application(location(), lhs, rhs, false)
}
//////////////////////////////////////////////////////////////////////
// Abstraction
//////////////////////////////////////////////////////////////////////
ABSTRACTION_W_PARENS "abstraction"
/*****************************************************************
'(' -> 'λ' -> Variable -> '.' -> TERM -> ')'
*****************************************************************/
= L_PARENS LAMBDA x:CHARACTER DOT term:TERM R_PARENS
{
return Abstraction(location(), x, term, true)
}
ABSTRACTION_WO_PARENS
/*****************************************************************
'λ' -> Variable -> '.' -> Term
*****************************************************************/
= LAMBDA x:CHARACTER DOT term:TERM
{
return Abstraction(location(), x, term, false)
}
//////////////////////////////////////////////////////////////////////
// Atoms
//////////////////////////////////////////////////////////////////////
LAMBDA "lambda"
= 'λ'
L_PARENS "lParens"
= '('
R_PARENS "rParens"
= ')'
DOT "dot"
= [\.]
CHARACTER "character"
= [A-Za-z]
{
return text().trim() ;
}
这在简单的输入上编译和运行良好。当我开始通过示例来测试实现时,我发现了一些问题。给定术语
λl.λm.λn.lmn
它解析成
{
"expr": "λl.λm.λn.lmn",
"ast": " Abstraction( l, Abstraction( m, Abstraction( n, Application( Variable( l ), Application( Variable( m ), Variable( n ) ) ) ) ) )"
}
问题出在左应用 m 应应用于 l,然后 n 应用于该结果。从 AST 的打印输出中可以看出,n 应用于 m,结果应用于 l,这是不正确的。
如果我更改现有规则以防止左递归问题,其中应用程序假定左侧只是一个变量或抽象以包含应用程序的可能性 - 那么就会出现递归问题。
我介绍了 parens 的概念 - 但我停止将它们整合进去。我真的不希望它们出现在语法中。
最佳答案
有缺陷的方法:我试过的一种方法是强制匹配两个以上的变量 |连续抽象并向左应用它们
APP_2
= lhs:ABSTRACTION_OR_VARIABLE rhs:ABSTRACTION_OR_VARIABLE
{
return Application(location(), lhs, rhs, false, "APP2")
}
APP_3
= lhs:APP_2 rhs:TERM
{
return Application(location(), lhs, rhs, false, "APP3")
}
APPLICATION_WO_PARENS
= APP_3
/ APP_2
当应用程序包含三个术语时,这看起来很有效。当有四个时,我们得到一棵 2 层的平衡树,而我们想要一棵三层的不平衡树……所以这是前一个 PEG 的错误输出(输入为 lmno):
{
"expr": "lmno",
"ast": "Application::APP3(
Application::APP2( Variable(l), Variable(m) ),
Application::APP2( Variable(n), Variable(o) )
)"
}
因此我可以构建任意数量的 APP_2 ... APP_99 规则并强制执行左侧应用程序。哪个可行 - 直到我超过 99(或其他)申请数量。解决方案将是一个真正的黑客和脆弱的。
工作 Hack 方法:想要一起破解一些东西,我改变了匹配一组术语作为应用程序的方法:
APP_ARR
= terms:ABSTRACTION_OR_VARIABLE*
{
return reduceTerms(location(), terms)
}
APPLICATION_WO_PARENS
= APP_ARR
这种方法需要我编写一些代码来构建我试图避免的结构 (reduceTerms)。这是代码:
const reduceTerms = function(info, terms){
const initialLhs = terms.shift()
const initialRhs = terms.shift()
const initialApp = Application(info, initialLhs, initialRhs, false, 'reduceTerms')
const appAll = terms.reduce(
(lhs, rhs) => Application(info, lhs, rhs, false, 'reduceTerms'),
initialApp
)
return appAll ;
}
请忽略 bool 值和'reduceTerms' 字符串。 bool 值用于指示此应用程序是否包含在括号内(将删除括号概念,直到我在本书后面遇到它)。字符串是关于我如何/在何处构造此应用程序 Node 实例的标签(以调试解析器如何应用规则)。
reduceTerms 函数是将数组简单地缩减到应用程序树中,应用左侧应用程序中的术语。初始对象是 terms 数组中左侧两项的应用程序。 reducing 函数会将初始对象作为 lhs 并将下一项作为 rhs,这正是您想要的。这是工作输出:
{
"expr": "lmno",
"ast": "Application::reduceTerms(
Application::reduceTerms(
Application::reduceTerms( Variable(l), Variable(m) ),
Variable(n) ),
Variable(o) )"
}
这里的一个问题是我需要做一些额外的工作来让 info 对象准确地反射(reflect)匹配。在此版本中,info 对象包含匹配所有术语的范围。虽然这并不重要,但最好能将所有这些联系起来。
所以我仍在寻找一种解决方案,它可以在 PEG 内部执行此操作,而无需在数组上进行匹配并缩减为树。
移除左递归的进展:使用已发布的翻译方法
A -> A α | β
到
A -> β A'
A' -> α A' | ε
在 PEG 中我有
TERM_OR_VARIABLE
= L_PARENS TERM R_PARENS
/ VARIABLE
APP
= lhs:TERM_OR_VARIABLE rhs:APP_
{
return Application(location(), lhs, rhs, false, "APP")
}
APP_
= lhs:TERM_OR_VARIABLE rhs:APP_
{
return Application(location(), lhs, rhs, false, "APP_")
}
/ lhs:TERM_OR_VARIABLE END
{
return lhs
}
/ END
END
= !.
APPLICATION_WO_PARENS
= APP
我现在能够解析应用程序 lmno 但 AST 是从右到左的应用程序
Application::APP(
Variable(l),
Application::APP_(
Variable(m),
Application::APP_(
Variable(n),
Variable(o)
)
)
)
关于javascript - 在保持左结合性的同时避免左递归解析 Lambda 微积分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51910361/
微积分运算在机器学习领域扮演着至关重要的角色,它不仅是许多基础算法和模型的核心,还深刻影响着模型的优化、性能评估以及新算法的开发。 掌握微积分,不仅让我们多会一种计算方式,也有助于理解各种机器学习算
我正在用 java 开发一个程序,它将找到给定函数的集成。例如 cos(x+3x^2)。现在我想检查用户是否给出了正确的输入。在检查输入的有效性时是否有任何正则表达式可以使用?例如,输入必须始终以积分
最近在研究lambda的计算,对reduction和substitution有很多疑惑。什么是 alpha 和 beta 缩减?何时以及为何使用它们? 如果有人能说出任何关于 lambda 微积分中减
我正在尝试利用 JavaScript 和 PEG.JS 将 lambda 演算项解析为 AST。语法相当简单: /*******************************************
我目前正在学习 Haskell,并且还在大学参加关于函数式编程的相当理论的讲座。 我知道这纯粹是理论/学术问题,但是我很感兴趣如何用纯 lambda 演算(即没有定义任何常量)简单地表达不同的简单函数
是否有任何合适的积分和微分算法,我可以用 C++ 或 C 来实现。只需将其命名为引用即可。如果您愿意提供示例代码,我将非常高兴您的回答和解释。提前致谢。 最佳答案 您可以使用 Calculus c++
我正在使用 Maths commons 来解决一些矩阵和复数但我现在想整合和区分所有类型的功能但正在阅读Polynomials section 我真的不知道该怎么做。我需要一些帮助关于如何使用此库创建
我正在尝试使用 clisp Lambda Calc 实现除法函数。风格 我读自this一个部门的 lambda 表达式是: Y (λgqab. LT a b (PAIR q a) (g (SUCC q
我正在尝试实现 Church Pair Lambda Calc。使用 CLisp 风格。 根据维基百科: pair ≡ λx.λy.λz.z x y 到目前为止,这是我的代码: (defvar PA
我安装了 ccx(Calculix 求解器程序)来解决物理问题。预处理器 cgx 工作正常,但是当我在终端中使用 .inp 文件 (abaqus) 运行 ccx 时,出现错误: ccx: symbol
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 7年前关闭。 Improve thi
我正在尝试构建一个接受给定数量的参数并始终返回相同值的函数。 这是作业的一部分。提供了一个提示: The "k-way T" is a function that takes k arguments
我正在 Haskell 中实现一个不纯的非类型 lambda 演算解释器。 我目前坚持实现“alpha-congruence”(在某些教科书中也称为“alpha-equivalence”或“alpha
我正在尝试构建一个接受给定数量的参数并始终返回相同值的函数。 这是作业的一部分。提供了一个提示: The "k-way T" is a function that takes k arguments
我是一名优秀的程序员,十分优秀!