Charles.Forsyth20060303-partialeea662d19 years agoHistory
349 lines · 6.1 KB · Text
RawDownload
.TH YACC 1.SH NAMEyacc \- yet another compiler-compiler (Limbo version).SH SYNOPSIS.B yacc[.I option ...].I grammar.SH DESCRIPTION.I Yaccconverts a context-free grammar and translation codeinto a set oftables for an LR(1) parser and translator.The grammar may be ambiguous;specified precedence rules are used to break ambiguities..PPThe output from.I yaccis a Limbo module.B y.tab.bcontaining the parse function.B yyparsewhich must be provided with a.B YYLEXadt providing the parser access to a lexical analyserroutine.BR lex() ,an error routine.BR error() ,and any other context required..PPThe options are.TP "\w'\fL-o \fIoutput\fLXX'u".BI -o " outputDirect output to the specified file instead of.BR y.tab.b ..TP.BI -D nCreate file.BR y.debug ,containing diagnostic messages.To incorporate them in the parser, give an.I ngreater than zero.The amount of diagnostic output from the parser is regulated byvalue.IR n :.RS .TP1Report errors..TP2Also report reductions..TP3Also report the name of each token returned by.LR yylex ..RE.TP.B -vCreate file.BR y.output ,containing a description of the parsing tables and ofconflicts arising from ambiguities in the grammar..TP.B -dCreate file.BR y.tab.m ,containing the moduledeclaration for the parser, along withdefinitions of the constantsthat associate.IR yacc -assigned`token codes' with user-declared `token names'.Include it in source files other than.B y.tab.bto give access to the token codes and the parser module..TP.BI -s " stemChange the prefix.L y of the file names.BR y.tab.b ,.BR y.tab.m ,.BR y.debug ,and.B y.outputto.IR stem ..TP.B -mNormally.I yaccdefines the type of the.B y.tab.bmodule within the text of the module accordingto the contents of the.B %moduledirective.Giving the.B -moption suppresses this behaviour, leaving the implementationfree to define the module's type from an external.B .mfile. The module's type name is still taken from the.B %moduledirective..TP.BI -n " sizeSpecify the initial.I sizeof the token stack created for theparser (default: 200)..SS Differences from C yaccThe Limbo.I yaccis in many respects identical to the C.IR yacc .The differences are summarised below:.PPComments follow the Limbo convention (a.B #symbol gives a comment until the end of the line)..PPA.B %moduledirective is required, which replaces the.B %uniondirective. It is of the form:.RS.IP.B %module.I modname.B {.br.I 	module types, functions and constants.br.B }.RE.B Modnamewill be the module's implementation type;the body of the directive, augmented with.B condefinitions for the.IR yacc -assignedtoken codes, gives the type of the module,unless the.B -moption is given, in which case no moduledefinition is emitted..PPA type.B YYSTYPEmust be defined, giving the typeassociated with.I yacctokens. Ifthe angle bracket construction is used afterany of the.BR %token ,.BR %left ,.BR %right ,.BR %nonassoc or.B %typedirectives in order to associate a type with a token or production,the word inside the angle bracketsrefers to a member of an instance of.BR YYSTYPE ,which should be an adt..PPAn adt.B YYLEXmust be defined, providing context to the parser.The definition must consist of at least the following:.EX	YYLEX: adt {		lval: YYSTYPE;		lex: fn(l: self ref YYLEX): int;		error: fn(l: self ref YYLEX, msg: string);	}.EE.B Lexshould invoke a lexical analyser to return thenext token for.I yaccto analyse. The value of the token shouldbe left in.BR lval ..B Errorwill be called when a parse error occurs..B Msgis a string describing the error..PP.B Yyparsetakes one argument, a reference to the.B YYLEXadt that will be used to provide it with tokens..PPThe parser is fully re-entrant;.I i.e.it does nothold any parse state in any global variableswithin the module..SH EXAMPLEThe following is a small but complete example of theuse of Limbo.I yaccto build a simple calculator..EX%{    include "sys.m";    sys: Sys;     include "bufio.m";    bufio: Bufio;    Iobuf: import bufio;     include "draw.m";     YYSTYPE: adt { v: real; };    YYLEX: adt {        lval:   YYSTYPE;        lex: fn(l: self ref YYLEX): int;        error: fn(l: self ref YYLEX, msg: string);    };%} %module Calc{    init:   fn(ctxt: ref Draw->Context, args: list of string);} %left   '+' '-'%left   '*' '/' %type   <v> exp uexp term%token  <v> REAL %%top :    | top '\en'    | top exp '\en'    {        sys->print("%g\en", $2);    }    | top error '\en'    ; exp : uexp    | exp '*' exp   { $$ = $1 * $3; }    | exp '/' exp   { $$ = $1 / $3; }    | exp '+' exp   { $$ = $1 + $3; }    | exp '-' exp   { $$ = $1 - $3; }    ; uexp    : term    | '+' uexp  { $$ = $2; }    | '-' uexp  { $$ = -$2; }    ; term    : REAL    | '(' exp ')'    {        $$ = $2;    }    ; %% in: ref Iobuf;stderr: ref Sys->FD; init(nil: ref Draw->Context, nil: list of string){	sys = load Sys Sys->PATH;	bufio = load Bufio Bufio->PATH;	in = bufio->fopen(sys->fildes(0), Bufio->OREAD);	stderr = sys->fildes(2);	lex := ref YYLEX;	yyparse(lex);} YYLEX.error(nil: self ref YYLEX, err: string){	sys->fprint(stderr, "%s\en", err);} YYLEX.lex(lex: self ref YYLEX): int{	for(;;){		c := in.getc();		case c{		' ' or '\et' =>			;		'-' or '+' or '*' or '/' or '\en' or '(' or ')' =>			return c;		'0' to '9' or '.' =>			s := "";			i := 0;			s[i++] = c;			while((c = in.getc()) >= '0' && c <= '9' ||			      c == '.' ||			      c == 'e' || c == 'E')				s[i++] = c;			in.ungetc();			lex.lval.v = real s;			return REAL;		* =>			return -1;		}	}}.EE.SH FILES.TF /lib/yaccpar.TP.B y.output.TP.B y.tab.b.TP.B y.tab.m.TP.B y.debug.TP.B /lib/yaccparparser prototype.SH SOURCE.B /appl/cmd/yacc.b.SH "SEE ALSO"S. C. Johnson and R. Sethi,``Yacc: A parser generator'',.IUnix Research System Programmer's Manual,Tenth Edition, Volume 2.brB. W. Kernighan and Rob Pike,.IThe UNIX Programming Environment,Prentice Hall, 1984.SH BUGSThe parser may not have full information when it writes to.B y.debugso that the names of the tokens returned by.L yylexmay be missing.