我编写了一个词法和解析器来分析线性代数语句。每个语句由一个或多个表达式组成,后面跟着一个或多个声明。我使用menhir和OCaml来编写词法和解析器。
例如: Ax = b,其中A是可逆的。
这应该理解为A*x= b,(A,可逆)
在表达式中,所有In都必须是大写或小写符号。我想重载乘法运算符,这样用户就不必输入'*‘符号。
但是,由于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有什么方法来分离单个字符并告诉解析器它们应该被当作乘法处理吗?是否有一种方法可以更改lexer,以便它足够聪明地知道逗号之前的所有字符集群都是Is,之后的所有集群都应该被视为字符串?
发布于 2014-04-20 16:29:00
在我看来你有两个问题:
我要解决的第一个问题是在雷克萨斯。
一个问题是为什么你说你需要使用字符串。这意味着你可以说一套完全开放的话。这可能是真的,但如果您可以将自己限制为一个较小的数字,则可以使用关键字而不是字符串。例如,invertible将是一个关键字。
如果您真的想在这样的地方允许任何字符串,那么绝对有可能黑掉一个lexer,这样它就可以保持一个描述它所看到的东西的状态,并且向前看,看看接下来会发生什么。如果不需要遵守预先定义的语法,则可以调整语法以使这更容易。(例如,只有一个目的可以使用逗号。)
对于第二个问题,我想说你需要在语法中添加邻接。也就是说,你的语法需要一个类似于term := term term的规则。我怀疑要使它正确工作是很棘手的,但是它确实在OCaml (相邻表达式代表函数应用程序)和awk (相邻表达式表示字符串连接)中工作。
https://stackoverflow.com/questions/23183937
复制相似问题