4

我在BNF 转换器上玩了一会儿,并尝试重新设计Mathematica语言的某些部分。我的 BNF 已经有大约 150 行并且运行良好,直到我注意到一个非常基本的错误。Mathematica中的括号[]用于两种不同的事物

  1. expr[arg]调用函数
  2. list[[spec]]访问表达式的元素,例如 aList

假设我想为一种只包含标识符、函数调用、元素访问和表达式序列作为参数的语言创建解析器。这些表格将是有效的

f[]
f[a]
f[a,b,c]
f[[a]]
f[[a,b]]

f[a,f[b]]
f[[a,f[x]]]

BNFC 的直接但明显错误的输入文件可能看起来像

entrypoints Expr ;

TSymbol.        Expr1 ::= Ident ;
FunctionCall.   Expr ::= Expr "[" [Sequence] "]" ;
Part.           Expr ::= Expr "[[" [Sequence] "]]" ;    
coercions Expr 1 ;

separator Sequence "," ;
SequenceExpr. Sequence ::= Expr ;

此 BNF 不适用于第一个代码块的最后两个示例。

问题似乎位于创建的Yylex词法分析器文件中,该文件匹配]并且]]分开。这是错误的,因为从最后一个例子可以看出,它是关闭]还是]]取决于上下文。因此,要么您必须创建一堆大括号以确保正确匹配,要么将其留给解析器。

有人可以告诉我是否可以通过 BNFC 实现这一点?

(顺便说一句,其他提示也将不胜感激)

4

1 回答 1

3

您的问题是令牌“]]”。如果词法分析器在没有任何过去记忆的情况下收集它,则可能是错误的。所以不要那样做!

根据定义,解析器会记住其左侧上下文,因此您可以让它正确地进行括号匹配。

我会这样定义你的语法:

FunctionCall.   Expr ::= Expr "[" [Sequence] "]" ;
Part.           Expr ::= Expr "[" "[" [Sequence] "]" "]" ;   

词法分析器仅检测单个“[”“]”作为标记。

一个奇怪的变体:

FunctionCall.   Expr ::= Expr "[" [Sequence] "]" ;
Part.           Expr ::= Expr "[[" [Sequence] "]" "]" ; 

词法分析器也检测“[[”作为标记,因为它不会被弄错。

于 2013-01-11T05:58:46.777 回答