我无法创建支持中缀、后缀和前缀函数等的语言有什么原因吗?
我一直在考虑创建一种非常适合创建 DSL 的语言,通过允许定义中缀、后缀、前缀甚至由多个单词组成的函数。 例如,您可以按如下方式定义中缀乘法运算符(其中已定义 multiply(X,Y)):
a * b => multiply(a,b)
或后缀“平方”运算符:
a squared => a * a
或者 C 或 Java 风格的三元运算符,其中涉及两个散布着变量的关键字:
a ? b : c => if a==true then b else c
显然,这种语言有很大的歧义范围,但如果它是静态类型的(带有类型推断),那么大多数歧义都可以被消除,而剩下的歧义可以被认为是语法错误(通过添加括号来纠正)在适当情况下)。
是否有某种我没有看到的原因会让这变得极其困难、不可能,或者只是一个简单的坏主意?
编辑:很多人向我指出了可以执行此操作或类似操作的语言,但我实际上对如何实现自己的解析器或我可能遇到的问题感兴趣如果这样做的话会遇到。
I've been mulling over creating a language that would be extremely well suited to creation of DSLs, by allowing definitions of functions that are infix, postfix, prefix, or even consist of multiple words. For example, you could define an infix multiplication operator as follows (where multiply(X,Y) is already defined):
a * b => multiply(a,b)
Or a postfix "squared" operator:
a squared => a * a
Or a C or Java-style ternary operator, which involves two keywords interspersed with variables:
a ? b : c => if a==true then b else c
Clearly there is plenty of scope for ambiguities in such a language, but if it is statically typed (with type inference), then most ambiguities could be eliminated, and those that remain could be considered a syntax error (to be corrected by adding brackets where appropriate).
Is there some reason I'm not seeing that would make this extremely difficult, impossible, or just a plain bad idea?
Edit: A number of people have pointed me to languages that may do this or something like this, but I'm actually interested in pointers to how I could implement my own parser for it, or problems I might encounter if doing so.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这并不难做到。 您需要为每个运算符分配一个固定性(中缀、前缀或后缀)和优先级。 使优先级为实数; 稍后你会感谢我的。 优先级较高的运算符比较优先级较低的运算符绑定得更紧密; 在相同的优先级下,您可以要求使用括号消除歧义,但您可能更愿意允许某些运算符关联,以便您可以在
不使用括号的情况下编写。 一旦您确定了每个运算符的固定性、优先级和关联性,您就需要编写一个运算符优先级解析器。 这种解析器的编写相当简单; 它从左到右扫描令牌并使用一个辅助堆栈。 龙书里有一个解释,但我从来没有发现它很清楚,部分原因是龙书描述了一个非常一般的运算符优先级解析的情况。 但我认为你不会觉得这很困难。
您需要注意的另一种情况是,其中
prefix
和postfix
具有相同的优先级。 这种情况也需要括号来消除歧义。我的论文 Unparsing Expressions with Prefix and Postfix Operators 有一个示例解析器在后面,你可以下载代码,但它是用 ML 编写的,所以它的工作原理对于业余爱好者来说可能并不明显。 但固定性等整个业务都得到了非常详细的解释。
This is not too hard to do. You'll want to assign each operator a fixity (infix, prefix, or postfix) and a precedence. Make the precedence a real number; you'll thank me later. Operators of higher precedence bind more tightly than operators of lower precedence; at equal levels of precedence, you can require disambiguation with parentheses, but you'll probably prefer to permit some operators to be associative so you can write
without parentheses. Once you have a fixity, a precedence, and an associativity for each operator, you'll want to write an operator-precedence parser. This kind of parser is fairly simply to write; it scans tokens from left to right and uses one auxiliary stack. There is an explanation in the dragon book but I have never found it very clear, in part because the dragon book describes a very general case of operator-precedence parsing. But I don't think you'll find it difficult.
Another case you'll want to be careful of is when you have
where
prefix
andpostfix
have the same precedence. This case also requires parentheses for disambiguation.My paper Unparsing Expressions with Prefix and Postfix Operators has an example parser in the back, and you can download the code, but it's written in ML, so its workings may not be obvious to the amateur. But the whole business of fixity and so on is explained in great detail.
您打算对操作顺序做什么?
What are you going to do about order of operations?
您可能想看看 Scala,它对运算符和方法有一种独特的方法。
You might want to check out Scala which has a kind of unique approach to operators and methods.
Haskell 正是您所寻找的。
Haskell has just what you're looking for.