我正在尝试为修改后的C语言编写C qi解析器。当我取消注释t_in_op及以下部分时,我得到一个运行时错误说明
语法错误:当索引1处的“+”时(或沿着这些行的某些东西,不记得确切),点击BEGIN。这个词法分析器有什么问题?
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace lex = boost::spirit::lex;
namespace qi = boost::spirit::qi;
namespace phoenix = boost::phoenix;
#include <boost/spirit/home/support/detail/lexer/runtime_error.hpp>
template <typename Lexer>
struct iLexer : lex::lexer<Lexer>
{
iLexer()
{
// define tokens and associate them with the lexer
identifier = "[a-zA-Z_][a-zA-Z_0-9]*";
intNum = "([0-9]+)|(0x[0-9a-fA-F]+)|(0b[01]+)";
floatNum = "(([0-9]+|(([0-9]+\\.[0-9]*[fF]?)|(\\.[0-9]+)))([eE][-+]?[0-9]+)?[fF]?)";
hexFloatNum = "(0x[01](\\.[0-9a-fA-F]*)?p[-+]?[0-9]+[fF]?)";
swizzle = "([01]+[w-z]+)+|([01]+[rgba]+)+|([01]+[uv]+)+";
t_inc_op = "++";
t_dec_op = "--";
// white space
ws = "[ \t\n]+";
this->self = ws [lex::_pass = lex::pass_flags::pass_ignore];
this->self += identifier
| floatNum
| hexFloatNum
| intNum
| swizzle
| t_inc_op
| t_dec_op
;
// these are passed on to parser as they are defined ('{' is passed as '{')
this->self += lex::token_def<>('(') | ')' | '{' | '}' | '=' | '<' | '>' | '&' | '|' | ';';
}
lex::token_def<> ws;
lex::token_def<> identifier, intNum, floatNum, hexFloatNum, swizzle;
lex::token_def<> t_inc_op, t_dec_op;
};
template <typename Iterator>
struct iGrammar : qi::grammar<Iterator>
{
template <typename TokenDef>
iGrammar(TokenDef const& tok)
// construct the base with the start symbol of our grammar
: iGrammar::base_type(translation_unit)
{
translation_unit
= *external_declaration
;
BOOST_SPIRIT_DEBUG_NODE(translation_unit);
external_declaration
= function_defnition
| declaration
;
BOOST_SPIRIT_DEBUG_NODE(external_declaration);
function_defnition
= (tok.identifier >> '(' >> ')')
;
BOOST_SPIRIT_DEBUG_NODE(function_defnition);
declaration
= ( tok.identifier >> '=' >> tok.intNum >> ';')
;
BOOST_SPIRIT_DEBUG_NODE(declaration);
}
qi::rule<Iterator> translation_unit;
qi::rule<Iterator> external_declaration;
qi::rule<Iterator> function_defnition;
qi::rule<Iterator> declaration;
};
int main(int argc, char* argv[])
{
// iterator type used to expose the underlying input stream
typedef std::string::iterator base_iterator_type;
// lexer type
typedef lex::lexertl::actor_lexer<
lex::lexertl::token<
base_iterator_type, boost::mpl::vector2<double, int>
> > lexer_type;
// iterator type exposed by the lexer
typedef iLexer<lexer_type>::iterator_type iterator_type;
// now we use the types defined above to create the lexer and grammar
// object instances needed to invoke the parsing process
iLexer<lexer_type> tokenizer; // Our lexer
iGrammar<iterator_type> g (tokenizer); // Our parser
std::string str (read_from_file("simple.ic"));
base_iterator_type first = str.begin();
try {
bool r = lex::tokenize_and_parse(first, str.end(), tokenizer, g);
if (r) {
std::cout << "-------------------------\n";
std::cout << "Parsing succeeded\n";
std::cout << "-------------------------\n";
}
else {
std::string rest(first, str.end());
std::cout << "-------------------------\n";
std::cout << "Parsing failed\n";
std::cout << "stopped at: \"" << rest << "\"\n";
std::cout << "-------------------------\n";
}
}
catch(const boost::lexer::runtime_error &re)
{
std::cerr << re.what() << std::endl;
}
std::cout << "Bye... :-) \n\n";
return 0;
}
simple.ic int i32 = 1;
答案 0 :(得分:2)
“+”字符在正则表达式中具有特殊含义。因此,您需要转义它以匹配普通的“+”:
t_inc_op = "\\+\\+";
您不需要在Spirit.Lex中转义特殊正则表达式字符的唯一例外是当您从单个字符定义标记时,例如
this->self += char_('+');
在这种情况下,库会为您进行转义。