Yacc. Generator of LALR(1) parsers. YACC = Yet Another Compiler Compiler symptom of two facts: Compiler. Compiler. Parser

Similar documents
Exercise 1 Codify in Yacc the generator of the abstract trees of the language defined by the following grammar:

Syntax Analysis Part IV

Exercise 1. int x = 3, num = 100; string A = "alpha", B = "beta"; boolean ok = true, end = false; Compilers Exercises on Lex

Using an LALR(1) Parser Generator

Introduction to Yacc. General Description Input file Output files Parsing conflicts Pseudovariables Examples. Principles of Compilers - 16/03/2006

CSCI Compiler Design

Compiler Lab. Introduction to tools Lex and Yacc

PRACTICAL CLASS: Flex & Bison

Lexical and Syntax Analysis

Compiler Design 1. Yacc/Bison. Goutam Biswas. Lect 8

Syntax-Directed Translation

Lex & Yacc (GNU distribution - flex & bison) Jeonghwan Park

Lesson 10. CDT301 Compiler Theory, Spring 2011 Teacher: Linus Källberg

Introduction to Lex & Yacc. (flex & bison)

An Introduction to LEX and YACC. SYSC Programming Languages

Lex & Yacc. by H. Altay Güvenir. A compiler or an interpreter performs its task in 3 stages:

Lab 2. Lexing and Parsing with Flex and Bison - 2 labs

Syntax Analysis Part VIII

Lex & Yacc. By H. Altay Güvenir. A compiler or an interpreter performs its task in 3 stages:

COMPILER CONSTRUCTION LAB 2 THE SYMBOL TABLE. Tutorial 2 LABS. PHASES OF A COMPILER Source Program. Lab 2 Symbol table

CSE302: Compiler Design

As we have seen, token attribute values are supplied via yylval, as in. More on Yacc s value stack

Principles of Programming Languages

Compiler construction in4020 lecture 5

Compiler construction 2002 week 5

LECTURE 11. Semantic Analysis and Yacc

Yacc: A Syntactic Analysers Generator

Prof. Mohamed Hamada Software Engineering Lab. The University of Aizu Japan

TDDD55 - Compilers and Interpreters Lesson 3

Yacc Yet Another Compiler Compiler

Compiler construction 2005 lecture 5

Hyacc comes under the GNU General Public License (Except the hyaccpar file, which comes under BSD License)

Parsing How parser works?

COMPILERS AND INTERPRETERS Lesson 4 TDDD16

A Bison Manual. You build a text file of the production (format in the next section); traditionally this file ends in.y, although bison doesn t care.

TDDD55- Compilers and Interpreters Lesson 3

I. OVERVIEW 1 II. INTRODUCTION 3 III. OPERATING PROCEDURE 5 IV. PCLEX 10 V. PCYACC 21. Table of Contents

Compiler Construction

Compiler Construction

Gechstudentszone.wordpress.com

COMPILER CONSTRUCTION Seminar 02 TDDB44

Big Picture: Compilation Process. CSCI: 4500/6500 Programming Languages. Big Picture: Compilation Process. Big Picture: Compilation Process.

Software II: Principles of Programming Languages

CS 403: Scanning and Parsing

CS143 Handout 12 Summer 2011 July 1 st, 2011 Introduction to bison

THE COMPILATION PROCESS EXAMPLE OF TOKENS AND ATTRIBUTES

Compilation 2013 Parser Generators, Conflict Management, and ML-Yacc

Syntax Analysis The Parser Generator (BYacc/J)

Syn S t yn a t x a Ana x lysi y s si 1

Parsing. COMP 520: Compiler Design (4 credits) Professor Laurie Hendren.

RYERSON POLYTECHNIC UNIVERSITY DEPARTMENT OF MATH, PHYSICS, AND COMPUTER SCIENCE CPS 710 FINAL EXAM FALL 96 INSTRUCTIONS

HW8 Use Lex/Yacc to Turn this: Into this: Lex and Yacc. Lex / Yacc History. A Quick Tour. if myvar == 6.02e23**2 then f(..!

Context-free grammars

Compiler Construction Assignment 3 Spring 2018

Compiler Construction: Parsing

Lexical and Parser Tools

About the Authors... iii Introduction... xvii. Chapter 1: System Software... 1

Compilerconstructie. najaar Rudy van Vliet kamer 124 Snellius, tel rvvliet(at)liacs.

More Assigned Reading and Exercises on Syntax (for Exam 2)

Chapter 3 -- Scanner (Lexical Analyzer)

Lex and Yacc. A Quick Tour

cmps104a 2002q4 Assignment 2 Lexical Analyzer page 1

Preface... (vii) CHAPTER 1 INTRODUCTION TO COMPUTERS

Introduction to Compilers and Language Design

Parsing and Pattern Recognition

flex is not a bad tool to use for doing modest text transformations and for programs that collect statistics on input.

Programming Project II

IBM. UNIX System Services Programming Tools. z/os. Version 2 Release 3 SA

Chapter 4. Lexical and Syntax Analysis

Last Time. What do we want? When do we want it? An AST. Now!

CSC 467 Lecture 3: Regular Expressions

Etienne Bernard eb/textes/minimanlexyacc-english.html

Yacc: Yet Another Compiler-Compiler

Chapter 2: Syntax Directed Translation and YACC

Lex and Yacc. More Details

LEX/Flex Scanner Generator

More On Syntax Directed Translation

LR Parsing. Leftmost and Rightmost Derivations. Compiler Design CSE 504. Derivations for id + id: T id = id+id. 1 Shift-Reduce Parsing.

Chapter 3: Describing Syntax and Semantics. Introduction Formal methods of describing syntax (BNF)

UNIT III & IV. Bottom up parsing

P.G.TRB - COMPUTER SCIENCE. c) data processing language d) none of the above

Big Picture: Compilation Process. CSCI: 4500/6500 Programming Languages. Big Picture: Compilation Process. Big Picture: Compilation Process

Automatic Scanning and Parsing using LEX and YACC

Appendix. Grammar. A.1 Introduction. A.2 Keywords. There is no worse danger for a teacher than to teach words instead of things.

Writing an ANSI C Program Getting Ready to Program A First Program Variables, Expressions, and Assignments Initialization The Use of #define and

TDDD55- Compilers and Interpreters Lesson 2

IN4305 Engineering project Compiler construction

Compiler Principle and Technology. Prof. Dongming LU April 15th, 2019

COP5621 Exam 3 - Spring 2005

COMPILER (CSE 4120) (Lecture 6: Parsing 4 Bottom-up Parsing )

EDAN65: Compilers, Lecture 06 A LR parsing. Görel Hedin Revised:

Chapter 3. Describing Syntax and Semantics ISBN

Parser Tools: lex and yacc-style Parsing

Decaf PP2: Syntax Analysis

Syntax Intro and Overview. Syntax

SEMANTIC ANALYSIS TYPES AND DECLARATIONS

Programming Language Syntax and Analysis

MIT Specifying Languages with Regular Expressions and Context-Free Grammars. Martin Rinard Massachusetts Institute of Technology

MIT Specifying Languages with Regular Expressions and Context-Free Grammars

CS 11 Ocaml track: lecture 6

Transcription:

Yacc Generator of LALR(1) parsers YACC = Yet Another Compiler Compiler symptom of two facts: 1. Popularity of parser generators in the 70s 2. Historically: compiler phases mixed within syntax analysis file.y Yacc file.c C Compiler Compiler parser input Parser output 1

Yacc (ii) Yacc specification: structurally identical to Lex Declarations %% Translation rules %% Auxiliary functions Declarations black box (auxiliary definitions): % #include, constants, variables %} white box (tokens, rules of precedence/associativity (for conflict resolution),... ) Example: calculator (interpreter) E E + T T T T * F F F ( E ) digit Left recursive 2

Yacc (iii) L E eol E E + T T T T * F F F ( E ) digit lexical attribute % #include <stdio.h> #include <ctype.h> int yylex() void yyerror() %} %token DIGIT %% line : expr '\n' printf("%d\n", $1) } expr : expr '+' term $$ = $1 + $3 } term term : term '*' factor $$ = $1 * $3 } factor factor : '(' expr ')' $$ = $2 } DIGIT %% int yylex() int c c = getchar() if (isdigit(c)) yylval = c '0' return(digit) } return(c) } 3 3 3 3 + 4 5 L 23 E 1 eol E 6 + T T F 7 digit digit 3 4 20 2 T 4 * F 4 5 4 8 F 5 digit 5 3 void yyerror()fprintf(stderr, "Syntax error\n")} void main()yyparse()} 3

Yacc (iv) 1. Declarations % C declarations %} declaration of terminals (tokens) of G %token DIGIT #define DIGIT 258 2. Translation rules = production rules + semantic actions A 1 2... n A : 1 action 1 } 2 action 2 }... n action n } Axiom = first nonterminal (default), or %start line 2 ways for token recognition '+' DIGIT 'c' = terminal symbol 'c' Nonterminal = string of alphanumeric characters Alternatives separated by Separation of each group of alternatives + semantic actions by Semantic action = fragment of C code Pseudo-variables to reference values of semantic attributes (default: integer) $$: left $i: i-th right 4

Yacc (v) yylval = variable containing lexical value of tokens assigned by lexical analyzer (value associated with terminal shifted onto the stack) Semantic action executed at a reduction $$ = f($1, $2,...) expr : expr '+' term $$ = $1 + $3} term default action: $$ = $1 3. Auxiliary functions = C functions necessary for completing the parsing function In particular: yylex() yyerror() called by yyparse() return 0: ok 1: error 5

Yacc (vi) G ambiguous conflicts detected by Yacc (option v : shows the solutions too) If conflicts consult file.output to view conflicts solutions Yacc rules for conflict resolutions: 1. Shift/reduce chosen the shift 2. Reduce/reduce chosen the first production (in file) Change of default of resolution for conflicts shift/reduce %left '+' ' ' %right '^' same precedence left associative right associative precedence associativity %nonassoc '<' non-associative (binary) operator a < b < c no! increasing precedence: %left '+' ' ' %left '*' '/' 6

Yacc (vii) precedence associativity that of the rightmost terminal Yacc implicitly defines a for production A Rule: Given the choice between shift a reduce A in a shift/reduce conflict: if precedence (A ) > precedence(a) or (precedence (A ) = precedence(a) and associativity(a ) = left) then Reduce A else Shift a a * b + c a + b + c a + b * c Example: E E + T. Conflict shift + reduce E E + T shift * reduce E E + T chosen Changing the precedence-default for a production (inherited from rightmost terminal): %prec <terminal> added to production defined in declarations expr : ' ' expr %prec UMINUS $$ = $2} 7

Yacc (viii) Extended calculator 1. List of expressions (one for each line) 2. Possible empty lines between different expressions 3. Spacing within expressions 4. Operator both unary and binary 5. Numbers with several digits L L E eol L eol E E + E E E E * E E / E ( E ) E num ambiguous L L L E eol eol E eol E eol eol eol E eol L eol L E eol L E eol 8

L L E eol L eol E E + E E E E * E E / E ( E ) E num Yacc (ix) % #include <stdio.h> #include <ctype.h> int yylex() void yyerror() %} %token NUM %left '+' ' ' %left '*' '/' %right UMINUS %% lines : lines expr '\n' printf("%d\n", $2)} lines '\n' /* */ expr : expr '+' expr $$ = $1 + $3} expr ' ' expr $$ = $1 $3} expr '*' expr $$ = $1 * $3} expr '/' expr $$ = $1 / $3} '(' expr ')' $$ = $2} ' ' expr %prec UMINUS $$ = $2} NUM %% int yylex() int c } while((c = getchar()) == ' ' c == '\t') if (isdigit(c)) ungetc(c, stdin) scanf("%d", &yylval) return(num) } return(c) void yyerror() fprintf(stderr, "Syntax error\n") } void main() yyparse() } 9

Yacc (x) Options of Yacc: to make visible definition of tokens -d (header) : generates file.h = declarations of exportable information #define YYSTYPE int Symbols for Lex extern YYSTYPE yylval -v (verbose) : generates file.output = description of LALR(1) parsing table Pragmatically: First: run Yacc on G (without semantic actions, auxiliary functions, etc.) to be sure that the generated parser conforms to expectations. Then: completion. YYDEBUG : Tracing of the execution of the parser generated by Yacc (not tracing of Yacc!) Symbol that must be defined, typically with -D option of C compiler: -DYYDEBUG Actual tracing enabled by integer variable yydebug: extern int yydebug yydebug = 1 list of the actions executed by the parser for a given input 10

Yacc (xi) Generalization of type of values computed by semantic actions (in other words: type of pseudo-variables, e.g. calculator for real values) %... #define YYSTYPE float... %} In general: different value types for different grammar symbols: float expr expr addop term term float float char term term mulop factor factor factor ( expr ) rnum addop + need to define YYSTYPE polymorphically = union float char char mulop * / 2 ways: managed by Yacc user 11

1. By %union... %union float value char operator} %type <value> expr term factor RNUM %type <operator> addop mulop %% line : expr '\n' printf("%f\n", $1)} Yacc (xii) line expr eol expr expr addop term term term term mulop factor factor factor ( expr ) rnum addop + mulop * / factor : '(' expr ')' $$ = $2} RNUM expr term : expr addop term switch($2) case '+': $$ = $1 + $3 break case ' ': $$ = $1 $3 break}} term : term mulop factor switch($2) case '*': $$ = $1 * $3 break case '/': $$ = $1 / $3 break}} factor addop : '+' $$ = '+'} ' ' $$ = ' '} mulop : '*' $$ = '*'} '/' $$ = '/'} 12

Yacc (xiii) 2. By defining the data type in a separate file typedef... TYPE #define YYSTYPE TYPE (in file Yacc) Value of TYPE constructed ad hoc within semantic actions $$.field = $1.field1 + $2.field2 Example: Construction of the syntax tree: typedef... *PNODE pointer to node of syntax tree 13

Yacc (xiv) % #include <ctype.h> #include <stdio.h> int yylex() void yyerror() typedef union float value char operator} Value #define YYSTYPE Value %} %token RNUM %% line : expr '\n' printf("%f\n", $1.value)} expr : expr addop term switch($2.operator) case '+': $$.value = $1.value + $3.value break case ' ': $$.value = $1.value $3.value break}} term term : term mulop factor switch($2.operator) case '*': $$.value = $1.value * $3.value break case '/': $$.value = $1.value / $3.value break}} factor line expr eol expr expr addop term term term term mulop factor factor factor ( expr ) rnum addop + mulop * / factor : '(' expr ')' $$.value = $2.value} RNUM addop : '+' $$.operator = '+'} ' ' $$.operator = ' '} mulop : '*' $$.operator = '*'} '/' $$.operator = '/'} 14

Yacc (xv) Embedded semantic actions: when necessary executing code before the complete recognition of a production decl type var-list type int float var-list id, var-list id int a, b, c Goal: Analyzing identifiers in var-list, qualify each id with relevant type. decl : type var list '' static variable 5 type decl 1 var-list 2 type : INT current_type = INT_TYPE} FLOAT current_type = FLOAT_TYPE} int id, var-list 3 var list : ID insert(yytext, current_type)} ',' var list ID insert(yytext, current_type)} id, var-list id 4 Interpretation of embedded actions by Yacc: E reduced after action on B A : B embedded action } C A : B E C E : embedded action } -production 15

Yacc (xvi) Internal identifiers of Yacc: Identifier file.c file.h yyparse() yylval YYSTYPE yydebug Description Name of output file Header file generated by Yacc (using -d), containing #define of tokens Parsing function Value of current token (in stack) Symbol for C preprocessor defining the type of values computed by semantic actions Integer variable enabling the execution of tracing of parser generated by Yacc Yacc definitions: Keyword %token %start %union %type %left %right %nonassoc Definition Symbol of preprocessing for tokens Axiom Union YYSTYPE to allow computing values of different types in semantic actions Variant type associated with a grammar symbol Left associativity for tokens Right associativity for tokens Non-associativity 16

Bottom-up Construction of (almost) Concrete Tree program stat-list stat-list stat stat-list stat stat def-stat assign-stat def-stat def id ( def-list ) def-list domain-decl, def-list domain-decl domain-decl id : domain domain integer string boolean assign-stat id := tuple-list } tuple-list tuple-const tuple-list tuple-const ( simple-const-list ) simple-const-list simple-const, simple-const-list simple-const simple-const intconst strconst boolconst program stat-list stat stat-list def-stat stat stat-list def id ( def-list ) def-stat stat stat-list assign-stat stat domain-decl, def-list assign-stat id : domain integer domain-decl id : domain, def-list domain-decl def R (A: integer, B: string, C: boolean) def S (D: integer, E: string) R := (3, "alpha", true)(5, "beta", false)} S := (125, "sun")(236, "moon")} string id : domain boolean 17

def.h #include <stdio.h> #include <stdlib.h> typedef enum NPROGRAM, NSTAT_LIST, NSTAT, NDEF_STAT, NDEF_LIST, NDOMAIN_DECL, NDOMAIN, NASSIGN_STAT, NTUPLE_LIST, NTUPLE_CONST, NSIMPLE_CONST_LIST, NSIMPLE_CONST } Nonterminal typedef enum T_INTEGER, T_STRING, T_BOOLEAN, T_INTCONST, T_BOOLCONST, T_STRCONST, T_ID, T_NONTERMINAL } Typenode typedef union int ival char *sval enum FALSE, TRUE} bval } Value typedef struct snode Typenode type Value value struct snode *child, *brother } Node typedef Node *Pnode char *newstring(char*) int yylex() Pnode nontermnode(nonterminal), idnode(), keynode(typenode), intconstnode(), strconstnode(), boolconstnode(), newnode(typenode) void treeprint(pnode, int), yyerror() 18

% #include "parser.h" #include "def.h" int line = 1 Value lexval %} %option noyywrap lexer.lex spacing ([ \t])+ letter [A Za z] digit [0 9] intconst digit}+ strconst \"([^\"])*\" boolconst false true id letter}(letter} digit})* sugar [()}:,] %% spacing} \n line++} def return(def)} integer return(integer)} string return(string)} boolean return(boolean)} intconst} lexval.ival = atoi(yytext) return(intconst)} strconst} lexval.sval = newstring(yytext) return(strconst)} boolconst} lexval.bval = (yytext[0] == 'f'? FALSE : TRUE) return(boolconst)} id} lexval.sval = newstring(yytext) return(id)} sugar} return(yytext[0])} ":=" return(assign)}. return(error)} %% char *newstring(char *s) char *p } p = malloc(strlen(s)+1) strcpy(p, s) return(p) 19

parser.h #define DEF 258 #define INTEGER 259 #define STRING 260 #define BOOLEAN 261 #define ID 262 #define INTCONST 263 #define STRCONST 264 #define BOOLCONST 265 #define ASSIGN 266 #define ERROR 267 20

parser.y % #include "def.h" #define YYSTYPE Pnode extern char *yytext extern Value lexval extern int line extern FILE *yyin Pnode root = NULL %} lexical analyzer program stat-list stat-list stat stat-list stat stat def-stat assign-stat program %token DEF INTEGER STRING BOOLEAN ID INTCONST STRCONST BOOLCONST ASSIGN %token ERROR stat-list %% program : stat_list root = $$ = nontermnode(nprogram) $$ >child = $1} stat-list stat-list stat_list : stat stat_list $$ = nontermnode(nstat_list) $$ >child = $1 $1 >brother = $2} stat $$ = nontermnode(nstat_list) $$ >child = $1} stat stat stat-list stat stat stat : def_stat $$ = nontermnode(nstat) $$ >child = $1} assign_stat $$ = nontermnode(nstat) $$ >child = $1} def-stat assign-stat 21

parser.y (ii) def-stat def id ( def-list ) def-list def-list, domain-decl domain-decl domain-decl id : domain domain integer string boolean def_stat : DEF ID $$ = idnode()} '(' def_list ')' $$ = nontermnode(ndef_stat) $$ >child = $3 $3 >brother = $5} def-stat id-node def-list def_list : domain_decl ',' def_list $$ = nontermnode(ndef_list) $$ >child = $1 $1 >brother = $3} domain_decl $$ = nontermnode(ndef_list) $$ >child = $1} def-list domain-decl def-list def-list domain-decl domain_decl : ID $$ = idnode()} ':' domain $$ = nontermnode(ndomain_decl) $$ >child = $2 $2 >brother = $4} domain-decl id-node domain domain : INTEGER $$ = nontermnode(ndomain) $$ >child = keynode(t_integer)} STRING $$ = nontermnode(ndomain) $$ >child = keynode(t_string)} BOOLEAN $$ = nontermnode(ndomain) $$ >child = keynode(t_boolean)} domain T_INTEGER domain T_STRING domain T_BOOLEAN 22

parser.y (iii) assign-stat id := tuple-list } tuple-list tuple-const tuple-list tuple-const ( simple-const-list ) assign_stat : ID $$ = idnode()} ASSIGN '' tuple_list '}' $$ = nontermnode(nassign_stat) $$ >child = $2 $2 >brother = $5} assign-stat id-node tuple-list tuple_list : tuple_const tuple_list $$ = nontermnode(ntuple_list) $$ >child = $1 $1 >brother = $2} $$ = nontermnode(ntuple_list)} tuple_const : '(' simple_const_list ')' $$ = nontermnode(ntuple_const) $$ >child = $2} tuple-list tuple-const tuple-list tuple-list tuple-const simple-const-list 23

parser.y (iv) simple-const-list simple-const, simple-const-list simple-const simple-const intconst strconst boolconst simple_const_list : simple_const ',' simple_const_list $$ = nontermnode(nsimple_const_list) $$ >child = $1 $1 >brother = $3} simple_const $$ = nontermnode(nsimple_const_list) $$ >child = $1} simple_const : INTCONST $$ = nontermnode(nsimple_const) $$ >child = intconstnode()} STRCONST $$ = nontermnode(nsimple_const) $$ >child = strconstnode()} BOOLCONST $$ = nontermnode(nsimple_const) $$ >child = boolconstnode()} %% simple-const-list simple-const-list simple-const simple-const-list simple-const simple-const simple-const simple-const intconstnode strconstnode boolconstnode 24

parser.y (v) Pnode nontermnode(nonterminal nonterm) Pnode p = newnode(t_nonterminal) p >value.ival = nonterm return(p) } Pnode idnode() Pnode p = newnode(t_id) p >value.sval = lexval.sval return(p) } Pnode keynode(typenode keyword) return(newnode(keyword)) } Pnode intconstnode() Pnode p = newnode(t_intconst) p >value.ival = lexval.ival return(p) } Pnode strconstnode() Pnode p = newnode(t_strconst) p >value.sval = lexval.sval return(p) } Pnode boolconstnode() Pnode p = newnode(t_boolconst) p >value.bval = lexval.bval return(p) } Pnode newnode(typenode tnode) Pnode p = malloc(sizeof(node)) p >type = tnode p >child = p >brother = NULL return(p) } int main() int result } yyin = stdin if((result = yyparse()) == 0) treeprint(root, 0) return(result) void yyerror() fprintf(stderr, "Line %d: syntax error on symbol \"%s\"\n", line, yytext) exit( 1) } 25

makefile bup: lexer.o parser.o tree.o cc g o bup lexer.o parser.o tree.o lexer.o: lexer.c parser.h def.h cc g c lexer.c parser.o: parser.c def.h cc g c parser.c tree.o: tree.c def.h cc g c tree.c lexer.c: lexer.lex parser.y parser.h parser.c def.h flex o lexer.c lexer.lex parser.h: parser.y def.h bison vd o parser.c parser.y 26

Bottom-up Construction of Abstract Tree (EBNF-like) program stat-list stat-list stat stat-list stat stat def-stat assign-stat def-stat def id ( def-list ) def-list domain-decl, def-list domain-decl domain-decl id : domain domain integer string boolean assign-stat id := tuple-list } tuple-list tuple-const tuple-list tuple-const ( simple-const-list ) simple-const-list simple-const, simple-const-list simple-const simple-const intconst strconst boolconst program stat stat } stat def-stat assign-stat def-stat def id ( def-list ) def-list id : domain, id: domain } domain integer string boolean assign-stat id := tuple-const } } tuple-const ( simple-const, simple-const } ) simple-const intconst strconst boolconst def R (A: integer, B: string, C: boolean) def S (D: integer, E: string) R := (3, "alpha", true)(5, "beta", false)} S := (125, "sun")(236, "moon")} 27

Bottom-up Construction of Abstract Tree (EBNF-like) (ii) stat def-stat program stat-list stat stat-list stat-list program stat stat } stat def-stat assign-stat def-stat def id ( def-list ) def-list id : domain, id: domain } domain integer string boolean assign-stat id := tuple-const } } tuple-const ( simple-const, simple-const } ) simple-const intconst strconst boolconst def id ( def-list ) def-stat stat stat-list domain-decl id : domain integer, domain-decl id : domain string def-list, def-list domain-decl id : domain boolean assign-stat stat assign-stat id := tuple-list } tuple-const ( simple-const-list ) simple-const, simple-const-list tuple-const tuple-list tuple-list child brother intconst simple-const strconst 28

Bottom-up Construction of Abstract Tree (EBNF-like) (iii) stat program stat-list stat-list program stat-list stat-list stat stat-list stat stat def-stat assign-stat def-stat stat stat-list def-stat stat stat-list assign-stat stat assign-stat program : stat_list root = $$ = nontermnode(nprogram) $$ >child = $1} stat_list : stat stat_list $$ = $1 $1 >brother = $2} stat $$ = $1} stat : def_stat $$ = nontermnode(nstat) $$ >child = $1} assign_stat $$ = nontermnode(nstat) $$ >child = $1} 29

Bottom-up Construction of Abstract Tree (EBNF-like) (iv) def-stat def id ( def-list ) domain-decl, def-list def-stat def id ( def-list ) def-list domain-decl, def-list domain-decl domain-decl id : domain domain integer string boolean id : domain domain-decl, def-list integer id : domain domain-decl string id : domain boolean def_stat : DEF ID $$ = idnode()} '(' def_list ')' $$ = nontermnode(ndef_stat) $$ >child = $3 $3 >brother = nontermnode(ndef_list) $3 >brother >child = $5} def_list : domain_decl ',' def_list $$ = $1 $1 >brother >brother = $3} domain_decl $$ = $1} domain_decl : ID $$ = idnode()} ':' domain $$ = $2 $2 >brother = $4} domain : INTEGER $$ = nontermnode(ndomain) $$ >child = keynode(t_integer)} STRING $$ = nontermnode(ndomain) $$ >child = keynode(t_string)} BOOLEAN $$ = nontermnode(ndomain) $$ >child = keynode(t_boolean)} 30

Bottom-up Construction of Abstract Tree (EBNF-like) (v) assign-stat id := tuple-list } tuple-const ( simple-const-list ) tuple-const tuple-list tuple-list assign-stat id := tuple-list } tuple-list tuple-const tuple-list tuple-const ( simple-const-list ) simple-const-list simple-const, simple-const-list simple-const simple-const intconst strconst boolconst simple-const, simple-const-list intconst simple-const strconst assign_stat : ID $$ = idnode()} ASSIGN '' tuple_list '}' $$ = nontermnode(nassign_stat) $$ >child = $2 $2 >brother = $5} tuple_list : tuple_const tuple_list $$ = $1 $1 >brother = $2} $$ = NULL} tuple_const : '(' simple_const_list ')' $$ = nontermnode(ntuple_const) $$ >child = $2} simple_const_list : simple_const ',' simple_const_list $$ = $1 $1 >brother = $3} simple_const $$ = $1} simple_const : INTCONST $$ = nontermnode(nsimple_const) $$ >child = intconstnode()} STRCONST $$ = nontermnode(nsimple_const) $$ >child = strconstnode()} BOOLCONST $$ = nontermnode(nsimple_const) $$ >child = boolconstnode()} 31