在 bisonc++ 中正确接受括号
Accept brackets correctly in bisonc++
我尝试使用 bisonc++
编写一个基本的语法检查器
规则是:
expression -> OPEN_BRACKET expression CLOSE_BRACKET
expression -> expression operator expression
operator -> PLUS
operator -> MINUS
如果我尝试 运行 编译后的代码,我会在这一行收到错误:
(a+b)-(c+d)
应用第一条规则,最左边和最右边的括号是OPEN_BRACKET
和CLOSE_BRACKET
。剩下的expression
是:a+b)-(c+d
如何防止这种行为?是否可以计算左括号和右括号?
编辑
表达式语法:
expression:
OPEN_BRACKET expression CLOSE_BRACKET
{
//
}
| operator
{
//
}
| VARIABLE
{
//
}
;
operator:
expression PLUS expression
{
//
}
| expression MINUS expression
{
//
}
;
编辑2
词法分析器
CHAR [a-z]
WS [ \t\n]
%%
{CHAR}+ return Parser::VARIABLE;
"+" return Parser::PLUS;
"-" return Parser::MINUS;
"(" return Parser::OPEN_BRACKET;
")" return Parser::CLOSE_BRACKET;
这不是正常的表达式语法。试试普通的。
expression
: term
| expression '+' term
| expression '-' term
;
term
: factor
| term '*' factor
| term '/' factor
| term '%' factor
;
factor
: primary
| '-' factor // unary minus
| primary '^' factor // exponentiation, right-associative
;
primary
: identifier
| literal
| '(' expression ')'
;
还要注意上面的缩进和对齐方法,对于单个特殊字符,你只需要从词法分析器 return yytext[0]
:你不需要特殊的标记名称,它是没有它们更具可读性:
CHAR [a-zA-Z]
DIGIT [0-9]
WHITESPACE [ \t\r\n]
%%
{CHAR}+ { return Parser::VARIABLE; }
{DIGIT}+ { return Parser::LITERAL; }
{WHITESPACE}+ ;
. { return yytext[0]; }
您的运算符规则看起来不太好。
尝试实验:
expression:
OPEN_BRACKET expression CLOSE_BRACKET
{
//
}
|
expression operator expression
{
//
}
|
VARIABLE
{
//
}
;
operator:
PLUS
{
//
}
|
MINUS
{
//
}
;
正如您的伪代码所暗示的那样...
我尝试使用 bisonc++
规则是:
expression -> OPEN_BRACKET expression CLOSE_BRACKET
expression -> expression operator expression
operator -> PLUS
operator -> MINUS
如果我尝试 运行 编译后的代码,我会在这一行收到错误:
(a+b)-(c+d)
应用第一条规则,最左边和最右边的括号是OPEN_BRACKET
和CLOSE_BRACKET
。剩下的expression
是:a+b)-(c+d
如何防止这种行为?是否可以计算左括号和右括号?
编辑
表达式语法:
expression:
OPEN_BRACKET expression CLOSE_BRACKET
{
//
}
| operator
{
//
}
| VARIABLE
{
//
}
;
operator:
expression PLUS expression
{
//
}
| expression MINUS expression
{
//
}
;
编辑2
词法分析器
CHAR [a-z]
WS [ \t\n]
%%
{CHAR}+ return Parser::VARIABLE;
"+" return Parser::PLUS;
"-" return Parser::MINUS;
"(" return Parser::OPEN_BRACKET;
")" return Parser::CLOSE_BRACKET;
这不是正常的表达式语法。试试普通的。
expression
: term
| expression '+' term
| expression '-' term
;
term
: factor
| term '*' factor
| term '/' factor
| term '%' factor
;
factor
: primary
| '-' factor // unary minus
| primary '^' factor // exponentiation, right-associative
;
primary
: identifier
| literal
| '(' expression ')'
;
还要注意上面的缩进和对齐方法,对于单个特殊字符,你只需要从词法分析器 return yytext[0]
:你不需要特殊的标记名称,它是没有它们更具可读性:
CHAR [a-zA-Z]
DIGIT [0-9]
WHITESPACE [ \t\r\n]
%%
{CHAR}+ { return Parser::VARIABLE; }
{DIGIT}+ { return Parser::LITERAL; }
{WHITESPACE}+ ;
. { return yytext[0]; }
您的运算符规则看起来不太好。
尝试实验:
expression:
OPEN_BRACKET expression CLOSE_BRACKET
{
//
}
|
expression operator expression
{
//
}
|
VARIABLE
{
//
}
;
operator:
PLUS
{
//
}
|
MINUS
{
//
}
;
正如您的伪代码所暗示的那样...