Branch
Hash :
36a5fa0e
Author :
Date :
2019-06-30T04:19:54
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 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
<h2>Comments</h2>
<pre><code>// Single-line comment
/* Multi-line
comment */</code></pre>
<h2>C prologue and Bison declarations</h2>
<pre><code>%{
#include <stdio.h>
#include <math.h>
int yylex (void);
void yyerror (char const *);
%}
%define api.value.type {double}
%token NUM
%union { char *string; }
%%
%%</code></pre>
<h2>Grammar rules</h2>
<pre><code>%%
exp:
NUM { $$ = $1; }
| exp exp '+' { $$ = $1 + $2; }
| exp exp '-' { $$ = $1 - $2; }
| exp exp '*' { $$ = $1 * $2; }
| exp exp '/' { $$ = $1 / $2; }
| exp exp '^' { $$ = pow($1, $2); } /* Exponentiation */
| exp 'n' { $$ = -$1; } /* Unary minus */
;
$@1: %empty { a(); };
$@2: %empty { c(); };
$@3: %empty { d(); };
exp: $@1 "b" $@2 $@3 "e" { f(); };
%%</code></pre>
<h2>Full example</h2>
<pre><code>/* Mini Calculator */
/* calc.y */
%{
#include "heading.h"
int yyerror(char *s);
int yylex(void);
%}
%union{
int int_val;
string* op_val;
}
%start input
%token <int_val> INTEGER_LITERAL
%type <int_val> exp
%left PLUS
%left MULT
%%
input: /* empty */
| exp { cout << "Result: " << $1 << endl; }
;
exp: INTEGER_LITERAL { $$ = $1; }
| exp PLUS exp { $$ = $1 + $3; }
| exp MULT exp { $$ = $1 * $3; }
;
%%
int yyerror(string s)
{
extern int yylineno; // defined and maintained in lex.c
extern char *yytext; // defined and maintained in lex.c
cerr << "ERROR: " << s << " at symbol \"" << yytext;
cerr << "\" on line " << yylineno << endl;
exit(1);
}
int yyerror(char *s)
{
return yyerror(string(s));
}</code></pre>