Dear all,<br> I wrote a little VC++ Parser using the Boost/Spirit Parser Framework [1] based in the Squeak EBNF grammar, which I took from the swiki [2]. I wonder if anyone here could tell what's the best way to run an automated test suite against a parser for Smalltalk from outside an image. <br>
I want to isolate some expressions resulting in recursion loops for my parser, I include the source below just in case anybody wants to take a look. Sorry for the long e-mail or uncorrect mailing list.<br><br>[1] <a href="http://spirit.sourceforge.net/">http://spirit.sourceforge.net/</a><br>
[2] <a href="http://wiki.squeak.org/squeak/409">http://wiki.squeak.org/squeak/409</a><br><br>// Requires - Spirit version 1.6.0 or later<br>#define BOOST_SPIRIT_DEBUG ///$$$ DEFINE THIS WHEN DEBUGGING $$$///<br><br>#include <boost/spirit/core.hpp><br>
#include <boost/spirit/symbols/symbols.hpp><br>#include <boost/spirit/utility/lists.hpp><br>#include <boost/spirit/utility/confix.hpp><br>#include <iostream><br>#include <fstream><br>#include <vector><br>
#include <string><br><br>////////////////////////////////<br>using namespace boost::spirit;<br>using namespace std;<br>//--------------------------------------------<br>// Start grammar definition<br>//--------------------------------------------<br>
struct st_grammar :<br> public grammar<st_grammar><br>{<br> template <typename ScannerT><br> struct definition<br> {<br> definition(st_grammar const& self)<br> {<br> chlit<> SUM('+');<br>
chlit<> SUB('-');<br> chlit<> MOD('\\');<br> chlit<> DIV('/');<br> chlit<> MUL('*');<br> chlit<> NOT('~');<br>
chlit<> LT('<');<br> chlit<> GT('>');<br> chlit<> EQ('=');<br> chlit<> AT('@');<br> chlit<> PC('%');<br>
chlit<> COMMA(',');<br> chlit<> CARET('^');<br><br>program = method | block | expression;<br><br>method = message_pattern <br> >> !temporaries <br> >> !primitive_declaration <br>
>> !statements;<br><br>message_pattern = unary_selector<br> | binary_selector >> argument_name <br> | +(keyword >> argument_name);<br><br>temporaries = confix_p('|', *variable_name, '|');<br>
<br>primitive_declaration = confix_p('<', str_p("primitive:") >> +digit_p, '>');<br><br>identifier = lexeme_d [ alpha_p >> *(alnum_p | digit_p) ];<br><br>binary_selector = SUM | SUB | MOD | DIV | MUL | NOT | LT | GT | EQ | AT | PC | COMMA;<br>
keyword = identifier >> ch_p(':');<br>argument_name = identifier;<br><br>block = <br> confix_p('[', <br> !(+(ch_p(':') >> argument_name) >> '|') >> <br> *temporaries >> *statements, ']');<br>
<br>statements = *(expression >> ch_p('.')) <br> >> !CARET <br> >> expression <br> >> !ch_p('.');<br><br>expression = *(variable_name >> assignment_op) <br>
>> ( cascaded_message_expression <br> | message_expression <br> | primary );<br><br>primary = confix_p('(', expression, ')') <br> | block <br> | literal <br> | argument_name <br>
| variable_name;<br><br>variable_name = identifier;<br><br>literal = array_constant <br> | strng <br> | character_constant <br> | symbol_constant <br> | number;<br><br>message_expression = keyword_expression <br>
| binary_expression <br> | unary_expression;<br><br>unary_selector = identifier >> ~eps_p(':');<br>unary_expression = primary >> +unary_selector;<br>unary_object_description = unary_expression | primary;<br>
<br>binary_object_description = binary_expression <br> | unary_object_description;<br><br>binary_expression = unary_object_description <br> >> binary_selector <br> >> unary_object_description;<br>
<br>// keyword_expression = binary_object_description % keyword;<br>keyword_expression = binary_object_description >> +(keyword >> binary_object_description);<br><br>cascaded_message_expression = message_expression <br>
>> +(ch_p(';') <br> >> ( unary_selector<br> | binary_selector >> unary_object_description<br> | +(keyword >> binary_object_description)));<br><br>character_constant = ch_p('$') <br>
>> (ch_p('\'') <br> | ch_p('\"') <br> | anychar_p);<br><br>array_constant = ch_p('#') >> array;<br>array = confix_p('(', *( number | symbol | strng | character_constant | array), ')');<br>
<br>symbol_constant = ch_p('#') >> symbol;<br>symbol = identifier <br> | binary_selector <br> | +(keyword) <br> | strng;<br><br>any_inumber = int_p | uint_p;<br>any_rnumber = real_p | ureal_p;<br>
<br>number <br> = !any_inumber <br> >> !ch_p('r') <br> >> (any_inumber ^ any_rnumber) <br> >> !(ch_p('e') >> (any_inumber));<br><br>strng = confix_p('\"', *(anychar_p - ch_p('\"')), '\"');<br>
<br>assignment_op = str_p(":=");<br><br>BOOST_SPIRIT_DEBUG_NODE(program);<br>BOOST_SPIRIT_DEBUG_NODE(method);<br>BOOST_SPIRIT_DEBUG_NODE(message_pattern);<br>BOOST_SPIRIT_DEBUG_NODE(temporaries);<br>BOOST_SPIRIT_DEBUG_NODE(primitive_declaration);<br>
BOOST_SPIRIT_DEBUG_NODE(identifier);<br>BOOST_SPIRIT_DEBUG_NODE(variable_name);<br>BOOST_SPIRIT_DEBUG_NODE(unary_selector);<br>BOOST_SPIRIT_DEBUG_NODE(binary_selector);<br>BOOST_SPIRIT_DEBUG_NODE(keyword);<br>BOOST_SPIRIT_DEBUG_NODE(argument_name);<br>
BOOST_SPIRIT_DEBUG_NODE(statements);<br>BOOST_SPIRIT_DEBUG_NODE(expression);<br>BOOST_SPIRIT_DEBUG_NODE(message_expression);<br>BOOST_SPIRIT_DEBUG_NODE(assignment_op);<br>BOOST_SPIRIT_DEBUG_NODE(primary);<br>BOOST_SPIRIT_DEBUG_NODE(cascaded_message_expression);<br>
BOOST_SPIRIT_DEBUG_NODE(literal);<br>BOOST_SPIRIT_DEBUG_NODE(block);<br>BOOST_SPIRIT_DEBUG_NODE(message_expression);<br>BOOST_SPIRIT_DEBUG_NODE(unary_expression);<br>BOOST_SPIRIT_DEBUG_NODE(binary_expression);<br>BOOST_SPIRIT_DEBUG_NODE(keyword_expression);<br>
BOOST_SPIRIT_DEBUG_NODE(binary_object_description);<br>BOOST_SPIRIT_DEBUG_NODE(unary_object_description);<br>BOOST_SPIRIT_DEBUG_NODE(strng);<br>BOOST_SPIRIT_DEBUG_NODE(number);<br>BOOST_SPIRIT_DEBUG_NODE(symbol);<br>BOOST_SPIRIT_DEBUG_NODE(symbol_constant);<br>
BOOST_SPIRIT_DEBUG_NODE(array);<br>BOOST_SPIRIT_DEBUG_NODE(array_constant);<br>BOOST_SPIRIT_DEBUG_NODE(character_constant);<br>BOOST_SPIRIT_DEBUG_NODE(any_rnumber);<br>BOOST_SPIRIT_DEBUG_NODE(any_inumber);<br>};<br><br>rule<ScannerT> const& start() const { return program; }<br>
<br>rule<ScannerT> <br> program, method, message_pattern, temporaries, <br> primitive_declaration, identifier,<br> variable_name, unary_selector, binary_selector, keyword, argument_name,<br> statements, expression, message_expression, primary, cascaded_message_expression,<br>
literal, block, assignment_op, unary_expression, binary_expression,<br> keyword_expression, binary_object_description, unary_object_description, <br> character_constant, array_constant, symbol_constant, array, symbol, number, strng,<br>
any_inumber, any_rnumber;<br> };<br>};<br><br>int main(int /*argc*/, char* /*argv[]*/) {<br> cout << "Write code in just a line\n\n" ;<br><br> st_grammar g;<br> BOOST_SPIRIT_DEBUG_NODE(g);<br>
<br> string str;<br> while (getline(cin, str))<br> {<br> if (str[0] == 'z' || str[0] == 'Z' )<br> break;<br><br> if (parse(str.c_str(), g, space_p).full)<br> {<br> cout << "parsing succeeded\n";<br>
}<br> else<br> {<br> cout << "parsing failed\n";<br> }<br> }<br> cout << "Bye... :-) \n\n";<br> return 0;<br>}<br><br>Cheers,<br><br>Hernán<br>