在使用boost精神规则时,如何避免语法歧义



我使用boost.spirit.x3为脚本语言构建语法,我在boost中找到了一个名为cal9的例子,我需要这样的东西,但它缺少if-else语句解析。因此,我在calc9的statement_def.cpp之上的语句定义中添加了以下代码。但在解析if_statement时,解析器会将if_statement识别为赋值语句,这不是我所期望的。我做错什么了吗?下面的代码是我修改过的版本,你可以与最初的cal9版本进行比较


namespace client { namespace parser
{
using x3::raw;
using x3::lexeme;
using namespace x3::ascii;

struct statement_list_class;
struct variable_declaration_class;
struct assignment_class;
struct variable_class;
struct if_statement_class;
typedef x3::rule<statement_list_class, ast::statement_list> statement_list_type;
typedef x3::rule<variable_declaration_class, ast::variable_declaration> variable_declaration_type;
typedef x3::rule<assignment_class, ast::assignment> assignment_type;
typedef x3::rule<variable_class, ast::variable> variable_type;
typedef x3::rule<if_statement_class, ast::if_statement> if_statement_type;
statement_type const statement("statement");
statement_list_type const statement_list("statement_list");
variable_declaration_type const variable_declaration("variable_declaration");
if_statement_type const if_statement("if_statement");
assignment_type const assignment("assignment");
variable_type const variable("variable");
// Import the expression rule
namespace { auto const& expression = client::expression(); }
auto const statement_list_def =
+(variable_declaration | assignment | if_statement )
;
auto const variable_declaration_def =
lexeme["var" >> !(alnum | '_')] // make sure we have whole words
>   assignment
;
/////below is what I added//////
auto const if_statement_def =
lexeme["if" >> !(alnum | '_')] // make sure we have whole words
> '('
> expression
> ')'
> '{'
> statement
> '}'
> -(lexeme["else" >> !(alnum | '_')] > '{' > statement > '}')
;
/////
auto const assignment_def =
variable
>   '='
>   expression
>   ';'
;

auto const variable_def = identifier;
auto const statement_def = statement_list;
BOOST_SPIRIT_DEFINE(
statement
, statement_list
, variable_declaration
, assignment
, if_statement
, variable
);
struct statement_class : error_handler_base, x3::annotate_on_success {};
struct assignment_class : x3::annotate_on_success {};
struct variable_class : x3::annotate_on_success {};
struct if_statement_class : x3::annotate_on_success {};
}}
namespace client
{
parser::statement_type const& statement()
{
return parser::statement;
}
}

您可以尝试的最简单的事情是重新排序分支,更改

auto const statement_list_def =
+(variable_declaration | assignment | if_statement )
;

进入

auto const statement_list_def =
+(variable_declaration | if_statement | assignment )
;

最新更新