385 |
Here is how to compile and run the parser file: |
Here is how to compile and run the parser file: |
386 |
|
|
387 |
# List files in current directory. |
# List files in current directory. |
388 |
% ls |
$ ls |
389 |
rpcalc.tab.c rpcalc.y |
rpcalc.tab.c rpcalc.y |
390 |
|
|
391 |
# Compile the Bison parser. |
# Compile the Bison parser. |
392 |
# `-lm' tells compiler to search math library for `pow'. |
# `-lm' tells compiler to search math library for `pow'. |
393 |
% cc rpcalc.tab.c -lm -o rpcalc |
$ cc rpcalc.tab.c -lm -o rpcalc |
394 |
|
|
395 |
# List files again. |
# List files again. |
396 |
% ls |
$ ls |
397 |
rpcalc rpcalc.tab.c rpcalc.y |
rpcalc rpcalc.tab.c rpcalc.y |
398 |
|
|
399 |
The file `rpcalc' now contains the executable code. Here is an |
The file `rpcalc' now contains the executable code. Here is an |
400 |
example session using `rpcalc'. |
example session using `rpcalc'. |
401 |
|
|
402 |
% rpcalc |
$ rpcalc |
403 |
4 9 + |
4 9 + |
404 |
13 |
13 |
405 |
3 7 + 3 4 5 *+- |
3 7 + 3 4 5 *+- |
411 |
3 4 ^ Exponentiation |
3 4 ^ Exponentiation |
412 |
81 |
81 |
413 |
^D End-of-file indicator |
^D End-of-file indicator |
414 |
% |
$ |
415 |
|
|
416 |
|
|
417 |
File: bison.info, Node: Infix Calc, Next: Simple Error Recovery, Prev: RPN Calc, Up: Examples |
File: bison.info, Node: Infix Calc, Next: Simple Error Recovery, Prev: RPN Calc, Up: Examples |
485 |
|
|
486 |
Here is a sample run of `calc.y': |
Here is a sample run of `calc.y': |
487 |
|
|
488 |
% calc |
$ calc |
489 |
4 + 4.5 - (34/(8*3+-3)) |
4 + 4.5 - (34/(8*3+-3)) |
490 |
6.880952381 |
6.880952381 |
491 |
-56 + 2 |
-56 + 2 |
539 |
====================================== |
====================================== |
540 |
|
|
541 |
This example extends the infix notation calculator with location |
This example extends the infix notation calculator with location |
542 |
tracking. This feature will be used to improve error reporting, and |
tracking. This feature will be used to improve the error messages. For |
543 |
provide better error messages. |
the sake of clarity, this example is a simple integer calculator, since |
544 |
|
most of the work needed to use locations will be done in the lexical |
545 |
For the sake of clarity, we will switch for this example to an |
analyser. |
|
integer calculator, since most of the work needed to use locations will |
|
|
be done in the lexical analyser. |
|
546 |
|
|
547 |
* Menu: |
* Menu: |
548 |
|
|
556 |
Declarations for `ltcalc' |
Declarations for `ltcalc' |
557 |
------------------------- |
------------------------- |
558 |
|
|
559 |
The C and Bison declarations for the location tracking calculator |
The C and Bison declarations for the location tracking calculator are |
560 |
are the same as the declarations for the infix notation calculator. |
the same as the declarations for the infix notation calculator. |
561 |
|
|
562 |
/* Location tracking calculator. */ |
/* Location tracking calculator. */ |
563 |
|
|
576 |
|
|
577 |
%% /* Grammar follows */ |
%% /* Grammar follows */ |
578 |
|
|
579 |
In the code above, there are no declarations specific to locations. |
Note there are no declarations specific to locations. Defining a data |
580 |
Defining a data type for storing locations is not needed: we will use |
type for storing locations is not needed: we will use the type provided |
581 |
the type provided by default (*note Data Types of Locations: Location |
by default (*note Data Types of Locations: Location Type.), which is a |
582 |
Type.), which is a four member structure with the following integer |
four member structure with the following integer fields: `first_line', |
583 |
fields: `first_line', `first_column', `last_line' and `last_column'. |
`first_column', `last_line' and `last_column'. |
584 |
|
|
585 |
|
|
586 |
File: bison.info, Node: Ltcalc Rules, Next: Ltcalc Lexer, Prev: Ltcalc Decls, Up: Location Tracking Calc |
File: bison.info, Node: Ltcalc Rules, Next: Ltcalc Lexer, Prev: Ltcalc Decls, Up: Location Tracking Calc |
588 |
Grammar Rules for `ltcalc' |
Grammar Rules for `ltcalc' |
589 |
-------------------------- |
-------------------------- |
590 |
|
|
591 |
Whether you choose to handle locations or not has no effect on the |
Whether handling locations or not has no effect on the syntax of your |
592 |
syntax of your language. Therefore, grammar rules for this example |
language. Therefore, grammar rules for this example will be very close |
593 |
will be very close to those of the previous example: we will only |
to those of the previous example: we will only modify them to benefit |
594 |
modify them to benefit from the new informations we will have. |
from the new information. |
595 |
|
|
596 |
Here, we will use locations to report divisions by zero, and locate |
Here, we will use locations to report divisions by zero, and locate |
597 |
the wrong expressions or subexpressions. |
the wrong expressions or subexpressions. |
615 |
else |
else |
616 |
{ |
{ |
617 |
$$ = 1; |
$$ = 1; |
618 |
printf("Division by zero, l%d,c%d-l%d,c%d", |
fprintf (stderr, "%d.%d-%d.%d: division by zero", |
619 |
@3.first_line, @3.first_column, |
@3.first_line, @3.first_column, |
620 |
@3.last_line, @3.last_column); |
@3.last_line, @3.last_column); |
621 |
} |
} |
622 |
} |
} |
623 |
| '-' exp %preg NEG { $$ = -$2; } |
| '-' exp %preg NEG { $$ = -$2; } |
628 |
using the pseudo-variables `@N' for rule components, and the |
using the pseudo-variables `@N' for rule components, and the |
629 |
pseudo-variable `@$' for groupings. |
pseudo-variable `@$' for groupings. |
630 |
|
|
631 |
In this example, we never assign a value to `@$', because the output |
We don't need to assign a value to `@$': the output parser does it |
632 |
parser can do this automatically. By default, before executing the C |
automatically. By default, before executing the C code of each action, |
633 |
code of each action, `@$' is set to range from the beginning of `@1' to |
`@$' is set to range from the beginning of `@1' to the end of `@N', for |
634 |
the end of `@N', for a rule with N components. |
a rule with N components. This behavior can be redefined (*note |
635 |
|
Default Action for Locations: Location Default Action.), and for very |
636 |
Of course, this behavior can be redefined (*note Default Action for |
specific rules, `@$' can be computed by hand. |
|
Locations: Location Default Action.), and for very specific rules, `@$' |
|
|
can be computed by hand. |
|
637 |
|
|
638 |
|
|
639 |
File: bison.info, Node: Ltcalc Lexer, Prev: Ltcalc Rules, Up: Location Tracking Calc |
File: bison.info, Node: Ltcalc Lexer, Prev: Ltcalc Rules, Up: Location Tracking Calc |
643 |
|
|
644 |
Until now, we relied on Bison's defaults to enable location |
Until now, we relied on Bison's defaults to enable location |
645 |
tracking. The next step is to rewrite the lexical analyser, and make it |
tracking. The next step is to rewrite the lexical analyser, and make it |
646 |
able to feed the parser with locations of tokens, as he already does |
able to feed the parser with the token locations, as it already does for |
647 |
for semantic values. |
semantic values. |
648 |
|
|
649 |
To do so, we must take into account every single character of the |
To this end, we must take into account every single character of the |
650 |
input text, to avoid the computed locations of being fuzzy or wrong: |
input text, to avoid the computed locations of being fuzzy or wrong: |
651 |
|
|
652 |
int |
int |
691 |
return c; |
return c; |
692 |
} |
} |
693 |
|
|
694 |
Basically, the lexical analyzer does the same processing as before: |
Basically, the lexical analyzer performs the same processing as |
695 |
it skips blanks and tabs, and reads numbers or single-character tokens. |
before: it skips blanks and tabs, and reads numbers or single-character |
696 |
In addition to this, it updates the `yylloc' global variable (of type |
tokens. In addition, it updates `yylloc', the global variable (of type |
697 |
`YYLTYPE'), where the location of tokens is stored. |
`YYLTYPE') containing the token's location. |
698 |
|
|
699 |
Now, each time this function returns a token, the parser has it's |
Now, each time this function returns a token, the parser has its |
700 |
number as well as it's semantic value, and it's position in the text. |
number as well as its semantic value, and its location in the text. The |
701 |
The last needed change is to initialize `yylloc', for example in the |
last needed change is to initialize `yylloc', for example in the |
702 |
controlling function: |
controlling function: |
703 |
|
|
704 |
int |
int |
711 |
|
|
712 |
Remember that computing locations is not a matter of syntax. Every |
Remember that computing locations is not a matter of syntax. Every |
713 |
character must be associated to a location update, whether it is in |
character must be associated to a location update, whether it is in |
714 |
valid input, in comments, in literal strings, and so on... |
valid input, in comments, in literal strings, and so on. |
715 |
|
|
716 |
|
|
717 |
File: bison.info, Node: Multi-function Calc, Next: Exercises, Prev: Location Tracking Calc, Up: Examples |
File: bison.info, Node: Multi-function Calc, Next: Exercises, Prev: Location Tracking Calc, Up: Examples |
737 |
to create named variables, store values in them, and use them later. |
to create named variables, store values in them, and use them later. |
738 |
Here is a sample session with the multi-function calculator: |
Here is a sample session with the multi-function calculator: |
739 |
|
|
740 |
% mfcalc |
$ mfcalc |
741 |
pi = 3.141592653589 |
pi = 3.141592653589 |
742 |
3.1415926536 |
3.1415926536 |
743 |
sin(pi) |
sin(pi) |
750 |
0.8329091229 |
0.8329091229 |
751 |
exp(ln(beta1)) |
exp(ln(beta1)) |
752 |
2.3000000000 |
2.3000000000 |
753 |
% |
$ |
754 |
|
|
755 |
Note that multiple assignment and nested function calls are |
Note that multiple assignment and nested function calls are |
756 |
permitted. |
permitted. |