Parsing 使用menhir和OCaml重载乘法

Parsing 使用menhir和OCaml重载乘法,parsing,ocaml,lexical-analysis,menhir,Parsing,Ocaml,Lexical Analysis,Menhir,我已经编写了一个词法分析器和解析器来分析线性代数语句。每个语句由一个或多个表达式和一个或多个声明组成。我正在使用menhir和OCaml来编写lexer和解析器 例如: Ax=b,其中A是可逆的 这应理解为A*x=b,(A,可逆) 在表达式中,所有ID必须是大写或小写符号。我想重载乘法运算符,以便用户不必键入“*”符号 但是,由于lexer还需要能够读取字符串(在本例中为“可逆”),因此表达式的“Ax”部分将作为字符串发送给解析器。这会导致解析器错误,因为在语句的表达式部分不应遇到字符串 下面是

我已经编写了一个词法分析器和解析器来分析线性代数语句。每个语句由一个或多个表达式和一个或多个声明组成。我正在使用menhir和OCaml来编写lexer和解析器

例如: Ax=b,其中A是可逆的

这应理解为A*x=b,(A,可逆)

在表达式中,所有ID必须是大写或小写符号。我想重载乘法运算符,以便用户不必键入“*”符号

但是,由于lexer还需要能够读取字符串(在本例中为“可逆”),因此表达式的“Ax”部分将作为字符串发送给解析器。这会导致解析器错误,因为在语句的表达式部分不应遇到字符串

下面是语法的基本概念

stmt :=
  | expr "."
  | decl "."
  | expr "," decl "."

expr :=
  | term
  | unop expr
  | expr binop expr

term :=
  | <int> num
  | <char> id
  | "(" expr ")"

decl :=
  | id "is" kinds

kinds :=
  | <string> kind
  | kind "and" kinds
stmt:=
|expr“
|decl“
|expr,“decl”
表达式:=
|术语
|unop expr
|expr binop expr
术语:=
|num
|身份证
|“(“expr”)”
十二月:=
|id“是”类
种类:=
|亲切的
|“种类”和“种类”

是否有某种方法来分离单个字符并告诉解析器它们应该被视为乘法?是否有一种方法可以更改lexer,以便它足够聪明地知道逗号前的所有字符簇都是ID,逗号后的所有簇都应该被视为字符串?

在我看来,您有两个问题:

  • 您希望lexer在不同的位置以不同的方式处理字符序列

  • 您希望乘法由相邻的表达式表示(中间没有运算符)

  • 我将在lexer中解决的第一个问题

    一个问题是为什么你说你需要使用字符串。这意味着你可以说一套完全开放的东西。这可能是真的,但如果你能把自己限制在一个很小的数字,你可以使用关键字而不是字符串。例如,
    inversible
    将是一个关键字

    如果您真的想在这些地方允许任何字符串,那么仍然可以破解lexer,使其保持一个状态,描述它所看到的,并展望未来。如果你不需要遵守预定义的语法,你可以调整你的语法使之更容易。(例如,逗号只能用于一个目的。)


    对于第二个问题,我认为你需要在语法中添加邻接。也就是说,你的语法需要一个规则,比如说
    term:=term
    。我怀疑要让它正常工作很难,但它在OCaml(相邻表达式表示函数应用程序)和awk(相邻表达式表示字符串串联)中确实有效。

    我和我的合作伙伴想到的解决方案是在lexer中定义关键字,这样它们就不能成为更大单词的一部分。所以“可逆”中的“in”不会注册为关键字(因为它后面有一个字符)。有没有标准的方法可以做到这一点?