help-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Accessing data structures in grammar


From: Leon Mergen
Subject: Accessing data structures in grammar
Date: Thu, 24 Nov 2005 08:02:20 +0100

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);
}



Attachment: smime.p7s
Description: S/MIME cryptographic signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]