2014-04-20 25 views
1

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

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

这应被理解为A * X = B,(A,可逆)

表达式中的所有的ID必须是一个大写或小写的符号。我想重载乘法运算符,以便用户不必输入'*'符号。但是,由于词法分析器也需要能够读取字符串(例如在本例中为“可逆”),因此表达式的“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 

的基本思想是有一些方法来单个字符分开,并告诉他们应该被视为乘法解析器?有没有办法改变词法分析器,以便足够聪明地知道逗号前的所有字符集都是id,并且之后的所有集群都应该被视为字符串?

回答

3

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

  1. 您希望您的词法分析器在不同的地方不同的方式处理的字符序列。

  2. 您希望乘法由邻接表达式指示(中间没有操作符)。

我会在词法分析器中解决的第一个问题。

一个问题是为什么你说你需要使用字符串。这意味着你可以说一些完全开放的东西。这可能是事实,但如果你能限制自己的数量,你可以使用关键字而不是字符串。例如,invertible将是一个关键字。

如果你真的想在这些地方允许任何字符串,那么仍然有可能破解一个词法分析器,以便它维护一个描述它所看到的状态的状态,并且展望未来会发生什么。如果您不需要遵循预定义的语法,则可以调整语法以使其更容易。 (例如,你可以只用一个逗号。)

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

+0

我的合作伙伴和我碰到的解决方案是在词法分析器中定义关键词,使它们不能成为大词汇的一部分。所以“in”中的“in”不会注册为关键字(因为它后面有一个字符)。有没有一个标准的方法来做到这一点? –