Hello, A question from a bison newbie: I'm having a bit of trouble since yesterday trying to get my grammar to access data member. Consider this grammar:
asm_parser.y: 1 %{ 2 #include <cstdlib> 3 #include <string> 4 #include <iostream> 5 #include <deque> 6 7 #include <stdarg.h> 8 9 #include "asm_parser.hpp" 10 11 #define YYSTYPE char 12 typedef char yystype; 13 typedef char yyltype; 14 typedef char yysigned_char; 15 extern int yylex(yystype *d); 16 17 class DataHolder { 18 public: 19 DataHolder () { 20 std::cout << __FILE__ << ":" << __LINE__ << " empty constructor" << std::endl; 21 } 22 DataHolder ( std::string data ) { 23 std::cout << __FILE__ << ":" << __LINE__ << " got data = '" << data << "'" << std::endl; 24 _data = data; 25 } 26 DataHolder ( char c ) { 27 std::cout << __FILE__ << ":" << __LINE__ << " got char='" << c << "'" << std::endl; 28 _data += c; 29 } 30 void addData ( char c ) { 31 std::cout << __FILE__ << ":" << __LINE__ << " got char='" << c << "'" << std::endl; 32 _data += c; 33 } 34 35 private: 36 std::string _data; 37 }; 38 39 %} 40 %union { 41 DataHolder data_t; 42 char char_t; 43 } 44 45 %token T_DATA 46 %token T_SUM_OPEN 47 %token T_SUM_CLOSE 48 %token T_VAR 49 50 %type<data_t> data 51 %type<char_t> T_DATA 52 53 54 %start template 55 56 %% 57 58 59 template: stream { std::cout << "template - stream" << std::endl; } 60 | stream template { 61 std::cout << "template - stream template" << std::endl; 62 } 63 ; 64 65 stream: command { std::cout << "stream - html_command" << std::endl; } 66 | data { 67 std::cout << "stream - data" << std::endl; 68 } 69 ; 70 71 command: sum { std::cout << "command - sum" << std::endl; } 72 | var { std::cout << "command - var" << std::endl; } 73 ; 74 75 sum: T_SUM_OPEN sumbody T_SUM_CLOSE { std::cout << "sum - T_SUM_OPEN sumbody T_SUM_CLOSE" << std::endl; } 76 ; 77 78 var: T_VAR { std::cout << "var - T_VAR" << std::endl; } 79 80 sumbody: template { std::cout << "sumbody - template" << std::endl; } 81 ; 82 83 data: T_DATA { 84 char c = $1; 85 $$.addData(c); 86 std::cout << "data - T_DATA " << std::endl; } 87 ; 88 %% 89 As you can see, at line 84 and 85, I try to read the data from the token and add it to the DataHolder class, which is the datatype of the non-terminal "data" as specified in 50 and 41. Now, when I try to compile this thing, it gives me this error (at the point where I'm compiling the bison-generated source code): `which flex` -oasm_scanner.cpp asm_scanner.l `which bison` -d -S lalr1.cc -o asm_parser.cpp asm_parser.y g++ -c -g -O0 main.c g++ -c -g -O0 asm_parser.cpp asm_parser.y: In member function `virtual int yy::Parser::parse()': asm_parser.y:84: error: request for member `char_t' in `(this + 44)->yy::Stack<T, S>::operator[] [with T = yystype, S = std::deque<yystype, std::allocator<char> >](0)', which is of non-class type `char' asm_parser.y:85: error: request for member `data_t' in `this->yy::Parser::yyval ', which is of non-class type `yystype' make: *** [asm_parser.o] Error 1 So basically, there's something wrong with my specification that has something to do with the datatype accessing... but I have /no/ idea what! Anyone here is able to help me ? This thing is bugging me for way too much time now.. :P Regards, Leon Mergen P.S. For completeness, here are my scanner source and main.c source: asm_scanner.l : 1 %{ 2 3 #include <iostream> 4 #include <string> 5 #include "asm_parser.hpp" 6 7 #define VARSIZE 64 /* Size of variable name can be 64 bytes max */ 8 9 char _sumvar[VARSIZE]; 10 11 extern void yyerror(const char* s); 12 13 #define YY_DECL int yylex(yystype *d) 14 15 %} 16 17 18 19 %x sumdata 20 21 %% 22 23 "<%"[a-z]+"%>" { 24 char * varPosition = _sumvar; 25 char * matchPosition = yytext; 26 27 matchPosition += 2; 28 29 for ( int i = 0; i < (sizeof(_sumvar) - 1); ++i ) { 30 if ( *matchPosition == '%' ) { 31 break; 32 } 33 *varPosition++ = *matchPosition++; 34 } 35 *varPosition = '\0'; 36 37 std::cout << __FILE__ << ":" << __LINE__ << " sum_open='" << _sumvar << "'" << std::endl; 38 39 BEGIN(sumdata); 40 return T_SUM_OPEN; 41 } 42 43 "<$"[ ]*[a-zA-Z0-9]+[ ]*"$>" { 44 char var[VARSIZE]; 45 parseVariableName ( (yytext + 2), var, '$' ); 46 std::cout << __FILE__ << ":" << __LINE__ << " var='" << var << "'" << std::endl; 47 return T_VAR; 48 } 49 50 <sumdata>"<$"[ ]*[a-zA-Z0-9]+[ ]*"$>" { 51 char var[VARSIZE]; 52 parseVariableName ( (yytext + 2), var, '$' ); 53 std::cout << __FILE__ << ":" << __LINE__ << " -sumdata- var='" << var << "'" << std::endl; 54 55 return T_VAR; 56 } 57 58 <sumdata>"<%"[a-z]+"%>" { 59 char sumvar[VARSIZE]; 60 /* 61 * First, make sure to read out the variable name... 62 */ 63 char * varPosition = sumvar; 64 char * matchPosition = yytext; 65 matchPosition += 2; 66 for ( int i = 0; i < (sizeof(sumvar) - 1); ++i ) { 67 if ( *matchPosition == '%' ) { 68 break; 69 } 70 *varPosition++ = *matchPosition++; 71 } 72 *varPosition = '\0'; 73 74 if ( strncmp(sumvar, _sumvar, sizeof(sumvar)) != 0 ) { 75 std::cout << "Document not well-formed: incorrect sum close tag '" << sumvar << "'" << std::endl; 76 exit(1); 77 } 78 79 std::cout << __FILE__ << ":" << __LINE__ << " -sumdata- close='" << sumvar << "', _sumvar = '" << _sumvar << "'" << std::endl; 80 BEGIN(INITIAL); 81 return T_SUM_CLOSE; 82 } 83 84 <sumdata>. { 85 std::cout << __FILE__ << ":" << __LINE__ << " -sumdata- data='" << yytext << "'" << std::endl; 86 return T_DATA; 87 } 88 89 90 . { 91 std::cout << __FILE__ << ":" << __LINE__ << " data ='" << yytext << "'" << std::endl; 92 return T_DATA; 93 } 94 95 %% main.c: #include "asm_parser.hpp" #include "asm_scanner.cpp" #include <string> namespace yy { void Parser::error_() { std::cout << __FILE__ << ":" << __LINE__ << ", error!" << std::endl; } void Parser::print_() { std::cout << __FILE__ << ":" << __LINE__ << ", print!" << std::endl; } }; int main () { int returnCode = 0; yy::Parser parser(true); std::string sCommand = "<html><title><$ title $>blaat<%we%><$ id $>bleet<$ name $><%we%>bloot<$ footer $></html>"; static yy_buffer_state *pBuffer; pBuffer = yy_scan_bytes(sCommand.c_str(), sCommand.size()); pBuffer->yy_at_bol = 1; yy_switch_to_buffer(pBuffer); returnCode = parser.parse(); std::cout << "returnCode = '" << returnCode << "'" << std::endl; yy_delete_buffer(pBuffer); }
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________ Help-bison@gnu.org http://lists.gnu.org/mailman/listinfo/help-bison