Parsing BNFC解析器和括号Mathematica-like语法

Parsing BNFC解析器和括号Mathematica-like语法,parsing,wolfram-mathematica,bnf,bnfc,Parsing,Wolfram Mathematica,Bnf,Bnfc,我和Mathematica玩了一会儿,并试图重新设计Mathematica语言的一些部分。我的BNF已经有大约150行了,工作正常,直到我注意到一个非常基本的错误。Mathematica中的括号[]用于两种不同的用途 expr[arg]调用函数 list[[spec]]访问表达式的元素,例如list 假设我想为一种只包含标识符、函数调用、元素访问和作为参数的表达式序列的语言创建解析器。这些表格是有效的 f[] f[a] f[a,b,c] f[[a]] f[[a,b]] f[a,f[b]] f[

我和Mathematica玩了一会儿,并试图重新设计Mathematica语言的一些部分。我的BNF已经有大约150行了,工作正常,直到我注意到一个非常基本的错误。Mathematica中的括号
[]
用于两种不同的用途

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

    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
    lexer文件中,该文件分别匹配
    ]
    ]
    。这是错误的,因为正如在上一个示例中所看到的,它是否是结束语取决于上下文。因此,要么创建大括号堆栈以确保正确匹配,要么将其留给解析器

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

    (顺便说一句,我们也会感激地接受其他提示)

    您的问题在于标记“]]”。如果lexer在没有 任何关于它过去的记忆,都可能是错误的。所以别那么做

    解析器根据定义记住其左上下文,因此您可以 正确匹配支架是非常重要的

    我会这样定义你的语法:

    FunctionCall.   Expr ::= Expr "[" [Sequence] "]" ;
    Part.           Expr ::= Expr "[" "[" [Sequence] "]" "]" ;   
    
    lexer只检测单个“[”“]”作为标记

    一个奇怪的变体:

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

    lexer还检测到“[[”作为标记,因为它不会出错。

    @HighPerformanceMark我这里不说前端,我说的是内核,它显然能够正确解析
    f[g[x]
    作为一个不完整的Mathematica解析器,我必须找到一个解决方案;不管它是否是Wolfram的糟糕设计。真正愚蠢的是,我已经有了这个解决方案,显然在尝试它时没有重新加载类:-(好的,这很有效。谢谢。或者,左括号中的lex表示,如果看到两个,则取两个,否则取一个(超过两个是错误条件)。对于右括号,使用解析器的状态告诉您一个词素中要放入多少个。这样可以保持单括号和双括号中词素的区别。我认为这是正确的做法(和=都是词素,但您不会为了形成:=)而单独使用它们).我的天哪,我刚刚意识到我之前的评论以一个不小心的表情结束。我想这预示着日子的结束或是什么。另一个需要注意词汇的原因。