V. Getting Started - A Small Example
V. Start now - a simple example
The purpose of this chapter teaches you how to use Pcyacc in a language development project. In order to achieve this goal, we assume that you are familiar with C language. We also assume that you have a Abraxas Pcyacc and a C Compiler.
This chapter gives you an overview of the program development process using Pcyacc. The example of this chapter is a simple calculator that can do ordinary algorithography. This example will show you - we temporarily named the Pcycc program list for Sacalc (Simple Arithmetic Calculator Program), while extinguing how to build executable Saccc with Pcyacc and C compiler, in a later chapter The development process will be described in detail with an example of a slightly higher level.
1. Sacalc's grammatical description file (Grammar Description file)
Below is the GDF code file of this simple calculator example: Sacc.y, in order to reference, we joined the line number (please note that the line number cannot appear in your GDL file) 01:% {
02:
03: #define yystype double / * stack data type * /
04:
05:%}
06:
07:% Token Number
08:% LEFT ' ' '-' / * Left associative * /
09:% LEFT '*' '/' / * left associative * /
10:% Left unaryminus
11:
12: %%
13:
14: list: / * Nothing * /
15: | List '/ N'
16: | List expr '/ n'
17: {Printf ("/ t% .8g / n", $ 2);
18: | List error '/ n'
19: {yherrok;}
20:;
twenty one:
22: EXPR: NUMBER
23: {$$ = $ 1;}
24: | '-' EXPR% PREC Unaryminus
25: {$$ = - $ 2;}
26: | EXPR ' ' EXPR
27: {$$ = $ 1 $ 3;
28: | EXPR '-' expr
29: {$$ = $ 1 - $ 3;
30: | EXPR '*' EXPR
31: {$$ = $ 1 * $ 3;
32: | EXPR '/' EXPR
33: {$$ = $ 1 / $ 3;
34: | '(' expr ')'
35: {$$ = $ 2;
36:;
37:
38: %%
39:
40: #include
41: #include
42: char * progName; / * for error message * /
43: int Lineno = 1;
44:
45: Main (Argc, Argv)
46: char * argv [];
47: {
48: ProgName = argv [0];
49: YYPARSE ();
50:}
51:
52: Yylex ()
53: {
54: INT C;
55:
56: While ((c = getchar ()) == '|| c ==' / t '); 57:
58: IF (c == EOF)
59: RETURN 0;
60: IF (c == '.' || isdigit (c)) {/ * number * /
61: UNGETC (C, STDIN);
62: Scanf ("% lf", & yylval);
63: RETURN NUMBER;
64:}
65: IF (c == '/ n')
66: LINENO ;
67: RETURN C;
68:}
69:
70: YYERROR (S) / * Called on Syntax Error * /
71: char * s;
72: {
73: Warning (s, (char *) 0);
74:}
75:
76: Warning (S, T) / * Print Warning Message * /
77: char * s, * t;
78: {
79: FPrintf (stderr, "% s:% s", progName, s);
80: IF (t) fprintf (stderr, "% s", t);
81: FPrintf (stderr, "near line% d / n", lineno);
82:}
83:
This short example shows a typical structure and component of a Pcyac DScription program. LINE12 to 37 forms a grammar rule section, developed and placed the literary rules of this language. LINE38 to 83 is a program section, where this compiler's C support code is placed. Just as seen in this example, a grammar description program consists of three parts: definition segment, grammar rules and blocks. The definition segment, the block can be empty (when no segment, the separator "%%" still needs, it tells Pcyacc to start processing the rules of the rules of writing.
The symbols that appear in Line1 and Line5 are a pair of separators, in the defined segments, they are used to include C's declarations, such as pre-processing instructions, global data structures definitions, or variable declarations (in this example, it is a pretreatment) Directive.) Pcycc does not view the code inside this separator. Anything in the separator will pass without change to the C program (ie, the compiler code generated)
Line7 declares that Number is a marker (Token), token is a symbol, which cannot be used on the left of the rules of grade. (When Yylex is called, we assume Yylex to return token's type .Number To be defined in a "#define" statement in generating code. If Yylex is not part of the program, it can also be put into A header file. When YyleX is called, the Generated Parser is expected to receive the type of token, such as the Number and the end of the flag file end.)
8 to 10 lines define the binding (Associative) related to the AritiTic Operators. All operators are defined (for example, in A B C, A B will be calculated first). These styles also convey the following information: plus ( ) and minus (-) have the same priority; multiply (*) and remove (/) have the same priority and higher than the addition; negative, this one Operator, has the highest priority. 12 lines are a separator, which sepaves the definition segment and the rules of grammar rules.
14 lines to 20 lines can simply do the following four rules: (1) list:;
(2) List: list '/ n';
(3) List: List expr '/ n';
(4) List: list error '/ n';
These rules say: A List can not only be empty (1), but can be followed by a LIST followed by a wrap symbol ('/ n') (2), but also a list follows an expression (expr). The wrap (3), or is a (Error) (ire) (4) (4) behind a List. In the simple symbol, the colon (:) is used to separate the left part of the rules. The vertical line (|) is an option to separately separate an ordinary left non-terminator, or the non-finalist. The semicolon (;) is used to end this rules of law. In the List grammar rules, 17 rows and 19 lines are additional instructions called behavior (Actions). Similar, 22 lines to 36 lines define the textual rules of Expressions.
The second "%%" separator has opened the grammar rule section and the program section. All things in the program are also copied to the Pcycc's output file. This section defines three C functions: main (), yylex (), yyrror (). Remember that in the Pcycc generated support generator, these three C functions are always needed. (They can be connected in different files simply when the program occurs). The following discussion will help you understand: How to make a complete C program with a written support function using the written support function with the programmer.
Pcycc's generating code is a C function: yyparse (), in technology, it is a Lalr Parser, a Lalr Parser, defined in a GDF file, a user's default main function: main ), It is used to activate the analyzer, and it needs to be initialized before the execution, and it needs to be released after activation. The lexical analyzer: Yylex () is an is The Front end of the parser. The Lexical Analyzer is considered to decompose the natural text string as meaningful vocabulary unit, this The vocabulary unit is called tokens, and this information is passed to the Parser. Error handling process: YYERROR (), when a syntax error is not discovered during the Parser resolution (Syntax Error) is not discovered. This function is called. The relationship between these four functions can be seen in the figure: These three segments: definition segments, grammar rules, blocks, and more discussions in the following chapters.
2. Establish Sacc that can be implemented
Call PCYACC to parse the syntax description file Sacc.y, use the following command: Pcyacc Sacc.y
3. Schacalc
When SacalC's executable code is successfully established (in our example, we have a Sacalc in the current directory), we can use it to perform simple arithmetic operations. Here is an example of Sacalc work: Sacc
1 2
3
2.5 4 * 1.5
8.5
2/4 - 3 * 0.5 / 3 5
5