Have been playing with Jison to try to create an "interpreter" for a very simple scripting syntax (this is just for a personal messing around project, no business case!)
It's been about 20 years since I had to create a compiler, and I think I'm just not grasping some of the concepts.
What I am thinking of doing is give a program of very simple statements, one per line, to Jison, and get a stream of Javascript statements back that then perform the actions.
I may be looking at this wrong - maybe I need to actually perform the actions during the parse? This doesn't sound right though.
Anyway, what I've got is (I'm trying this online btw http://zaach.github.io/jison/try/)
/* lexical grammar */
%lex
%options case-insensitive
%%
\s+ /* skip whitespace */
is\s+a\b return 'OCREATE'
is\s+some\b return 'ACREATE'
[_a-zA-Z]+[_a-zA-Z0-9]*\b return 'IDENTIFIER'
<<EOF>> return 'EOF'
/lex
/* operator associations and precedence */
%start input
%% /* language grammar */
input
: /* empty */
| program EOF
{ return $1; }
;
program
: expression
{ $$ = $1; }
| program expression
{ $$ = $1; }
;
expression
: IDENTIFIER OCREATE IDENTIFIER
{ $$ = 'controller.createOne(\'' + $1 + '\', \'' + $3 + '\');' }
| IDENTIFIER ACREATE IDENTIFIER
{ $$ = 'controller.createSeveral(\'' + $1 + '\', \'' + $3 + '\');' }
;
So, for the input:
basket is some apples
orange is a fruit
...I want:
controller.createSeveral('basket', 'apples');
controller.createOne('orange', 'fruit');
What I am getting is:
controller.createSeveral('basket', 'apples');
This kind of makes sense to me to get a single result, but I have no idea what to do to progress with building my output.
The problem is in your second production for program
:
program
: expression
{ $$ = $1; }
| program expression
{ $$ = $1; }
What the second production is saying, basically, is "a program can be a (shorter) program followed by an expression, but its semantic value is the value of the shorter program."
You evidently want the value of the program to be augmented by the value of the expression, so you need to say that:
program
: expression
{ $$ = $1; }
| program expression
{ $$ = $1.concat($2); }
(or $$ = $1 + $2
if you prefer. And you might want a newline for readability.)