我正在为一种处理向量的小语言编写翻译。我正在使用Flex和Bison。
使用以下符号声明向量:
v:= <1.4,-2.2,7>
因此,它们的成分也可以包含负数。这些向量支持的运算是加法,减法和标量乘法。因此,您不能添加向量和标量,不能减去向量和标量,但是可以将向量和标量相乘。
由于支持负数,所以我的词法分析器使用以下正则表达式来匹配数字:
[+-]?[0-9]+([.][0-9]+)? {yylval.somedub = atof(yytext); return NUMBER;}
解析以下格式的表达式时会发生此问题(当然,带加号的问题完全相同:]
v-2*v
它的解析方式是:vector minus (number times vector)
。但是,一旦flex看到-2,它将把它解释为一个数字,所以我得到vector (number) times vector
,这当然是没有意义的。另一方面,如果您要编写v - 2*v
,它会很好地工作,因为-
和2
之间有一个空格。我的语法的表达部分看起来像这样(我不会复制整个代码,因为它很大):
expression:
expression '+' level_1
| expression '-' level_1
| level_1
level_1:
NUMBER '*' level_1
| level_1 '*' NUMBER
| level_2
level_2:
'(' expression ')'
| vector //parses the whole <a, b, c, ..> notation, irrelevant for the problem
我还使用+声明了+,-和*为左关联
%left '+' '-'
%left '*'
那么我将如何解决这个问题?我不知道我是否需要以某种方式更改关联性或重构整个语法。
有什么想法吗?
谢谢。
如果-2
被识别为单个NUMBER
令牌,则意味着解析器将看到v-2
作为名称,后跟一个数字,并且在这一点上,您实际上无法执行任何操作来获取所需的解析。因此,应该将-2
识别为两个标记:减号后跟数字。
[要实现这一点,您可以简单地从正则表达式中删除数字的[+-]?
(我假设您已经有一个规则可以单独识别+
和-
)。
现在,您只需要调整语法以允许-
或+
后跟一个数字(或者如果您还想允许-v
或-(2+3)
之类的话,可以使用任何表达式)。