[Top][All Lists]
[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);
}
smime.p7s
Description: S/MIME cryptographic signature
- Accessing data structures in grammar,
Leon Mergen <=