我喜欢常见的口齿不清,但有时输入简单的数学表达式(如
)真的很痛苦a(8b^2+1)+4bc(4b^2+1)
(当然我可以转换它,但它有点慢,我先写(+()()),然后在每个括号中我放(*()())......)
我想知道这里是否有人知道更好的输入方法。我正在考虑编写一个数学宏,其中
(math “a(8b^2+1)+4bc(4b^2+1)”)
扩展为
(+ (* a (1+ (* 8 b b))) (* 4 b c (1+ (* 4 b b))))
但解析是名称很长的变量的问题。
有人有更好的建议吗?
答案 0 :(得分:25)
为此目的有读者宏。
请参阅:http://www.cliki.net/infix
例如:
CL-USER 17 > '#I(a*(8*b^^2+1)+ 4*b*c*(4*b^^2+1) )
(+ (* A (+ (* 8 (EXPT B 2)) 1)) (* 4 B C (+ (* 4 (EXPT B 2)) 1)))
'
是通常的引用。 #I( some-infix-expression )
是读者宏。
答案 1 :(得分:2)
我一直关注的一个项目是所谓的“Sweet Expressions”。该项目的目标是添加与s表达式向后兼容的“甜味”,并且足够简单,表达式不会妨碍宏。 (例如,已经观察到运算符优先级确实干扰了宏系统;因此,建议的解决方案不使用运算符优先级。)
应该记住,该项目还处于起步阶段,特别是Common Lisp;但是,该项目有一个中缀表示法的工作实现,它依赖于大括号和一个简单的算法:
{1 + {2 * 3} + {4 exp 5}}
很好地翻译成
(+ 1 (* 2 3) (exp 4 5))
我将引用您的链接,以更深入地讨论大括号的语义。
答案 2 :(得分:0)
我最近为此目的编写了一个cl宏,你可能会发现它很有用。它被称为ugly-tiny-infix-macro。
您可以将问题表达式写为:
($ a * ($ 8 * (expt b 2) + 1) + 4 * b * c * ($ 4 * (expt b 2) + 1))
它扩展到
(+ (* A (+ (* 8 (EXPT B 2)) 1)) (* (* (* 4 B) C) (+ (* 4 (EXPT B 2)) 1)))
<强>说明:强> $是宏的名称。这些参数被视为表达式列表,因此自由使用空格将数字/表单与表示运算符的符号分开。
考虑以下示例以更好地理解此宏的功能:
($ 1 + 2) ; gets converted to (+ 1 2), where name of the macro is $
($ t and nil) ; gets converted to (and t nil)
($ 3 > 5) ; gets converted to (> 3 5)
($ 1 + 2 + 3) ; gets converted to (+ (+ 1 2) 3)
($ 1 + 2 * 3) ; gets converted to (+ 1 (* 2 3))
($ 1 < 2 and 2 < 3) ; gets converted to (AND (< 1 2) (< 2 3))
操作数位置括号内的任何内容都被视为lisp形式。
($ 2 + (max 9 10 11)) ; gets converted to (+ 2 (max 9 10 11)). It could have been any function / lisp form.
($ 6 / ($ 1 + 2)) ; gets converted to (/ 6 ($ 1 + 2)), and then subsequently to (/6 (+ 1 2))
我发现它比读者宏更容易推理和更有利,因为它可能容易与lisp表单混合,因此您可以在表达式中嵌套lisp表单。例如,(exp b 2)
可能是任何lisp表单,例如(max a b c)
或您自己的用户定义的(foobar a b c)
。
您可以在github上找到有关README的更多信息。它也可以在quicklisp上找到。