need help with bison parser

closed account (Dy7SLyTq)
so im building a compiler for a language i designed called runescript, and am having some trouble parsing comments. to do this i am using flex, bison, and gcc4.8.1. i am on linux mint. i apologize if i left out any information. please let me know if i did and ill post it.

runescript.l:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
%{
#include "runescript.tab.h"
%}

DIGIT    [0-9]
ID       [a-zA-Z_][a-zA-Z_0-9]*
KEYWORD  import|function|foreach|in|return|and|asm|bool|break|case|catch|char|class|final|continue|default|do|float|else|enum|False|for|goto|if|elif|int|namespace|new|or|private|public|static|switch|this|throw|True|try|typedef|typeid|typename|using|while
OPERATOR ";"|"("|")"|"{"|"}"|","

%%

{DIGIT}+              { yylval.ival = atoi(yytext); return INT; }
{DIGIT}+"."{DIGIT}*   { yylval.fval = atof(yytext); return FLOAT; }
"."{DIGIT}+           { yylval.fval = atof(yytext); return FLOAT; }
"\""[^"\""]*"\""      { yylval.sval = strdup(yytext); return STRING; }
"'"[\"'"]*"'"         { yylval.sval = strdup(yytext); return STRING; }
{KEYWORD}             {  }
"/\*"[^"\*/"]*"\*/"   {  }
"$"+{ID}              {  }
({ID}+(\.rsc|\.rune)) {  }
{ID}                  {  }
{OPERATOR}            {  }
"//"[^"\n"]*          {  }
[ \t\n]+              ; /* Eat up whitespace */
.                     ; /* Eat up everything else */

%%


runescript.y:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
%{
#include <stdio.h>
#include <stdlib.h>

int yylex();
int yyparse();
FILE *yyin;
 
void yyerror(const char *s);
%}

%union {
	int ival;
	float fval;
	char *sval;
}

%token <bval> BOOL
%token <ival> INT
%token <fval> FLOAT
%token <sval> STRING

%left ','
%left '(' ')'

%%

statement_list : statement ';'
               | statement_list statement_list

statement: "import " file ';'
         | function_call
         | function_definition
         | "return" type ';'

file: STRING ".rsc"
    | STRING ".rune"
    | file file

function_call: STRING '(' arg_list ')' ';'

arg_list: /*empty*/
        | '$' type
        | arg_list ',' '$' type

type: INT
    | FLOAT
    | STRING

function_definition: "function" STRING '(' arg_list ')' '{' statement_list '}'

%%

int main(int argc, char **argv)
{
    ++argv, --argc;

    if(argc > 0) yyin = fopen(argv[0], "r");
    else yyin = stdin;

    yyparse();
}

void yyerror(const char *s)
{
    printf("error: %s\n", s);
	exit(-1);
}


hello.rune:
1
2
3
4
5
6
7
8
9
10
11
/*
    hello.rune
*/

import sysio.rsc, test.rsc, test.rune; //for echoln()

function main($args)
{
	echoln("Hello, world! test.rsc");
    return 0;
}


i then run:
1
2
3
4
5
dtscode@dtscode-Latitude-E6410 ~/Desktop/runescript $ bison -d runescript.y
runescript.y: conflicts: 5 shift/reduce #can anyone tell me why it says that?
dtscode@dtscode-Latitude-E6410 ~/Desktop/runescript $ flex runescript.l
dtscode@dtscode-Latitude-E6410 ~/Desktop/runescript $ gcc runescript.tab.c lex.yy.c -lfl -o runescript
dtscode@dtscode-Latitude-E6410 ~/Desktop/runescript $ 

however when i run ./runescript hello.rune it says error: syntax error.
Add the %debug directive to the .l, declare the <prefix>debug (prefix=yy by default) global int variable, and set it to 1 in main() before calling yyparse(). Make sure to run bison with --report all to print a report of the states and their transitions so you can follow the output that will be generated.

A shift/reduce conflict happens when the compiler compiler can't figure out what to do with certain token sequences. The canonical example is this:
What does "if a then if b then c else d" mean?
A. "if a then { if b then c else d }" (shift solution)
B. "if a then { if b then c } else b" (reduce solution)
"Shifting" means to push (or "shift", in parser parlance) the nonterminal symbol (in this example, the else block) into the symbol stack. This will later cause the parser to treat the then block and else block as part of the same if statement.
"Reducing" means to just reduce the token string as soon as possible. In the example, "if b then c" is a complete if statement, so it can be reduced immediately.
Bison solves shift/reduce conflicts by shifting. This is usually what was intended, but you should study each conflict carefully, as they usually indicate some design issue in your grammar.

The third production rule for 'file' is a s/r conflict. The string "a.rsc b.rsc c.rsc" is a 'file' that can be assembled from smaller 'file's in different ways:
* "((a.rsc) (b.rsc)) (c.rsc)"
* "(a.rsc) ((b.rsc) (c.rsc))"
The proper way to make lists in Yacc/Bison is
1
2
3
4
5
list_element: /*...*/;

possibly_empty_list: | possibly_empty_list list_element;

never_empty_list: list_element | never_empty_list list_element;
You have a similar problem in your definition of 'statement_list'.
closed account (Dy7SLyTq)
thanks helios! ill do all of those things you said (perhaps when im not so tired) and report back.
Topic archived. No new replies allowed.