?? parser.lma
字號:
/*@A (C) 1992 Allen I. Holub */
%{
#include <stdarg.h>
#include <tools/debug.h>
#include <tools/hash.h>
#include <tools/set.h>
#define CREATING_LLAMA_PARSER /* Suppress various definitions in parser.h */
#include "parser.h" /* that conflict with llama-generated defs. */
/* This file is a llama input file that creates a parser for llama, like a snake
* eating its tail. The resulting yyparse.c file can be used in place of the
* recursive-descent parser in llpar.c. Note that, though this file is certainly
* easier to write than the recursive-descent version, the resulting code is
* about 1K larger. nows() should be called before firing up the parser.
* Most of the external subroutines called from this module are in acts.c.
* Exceptions are:
*/
extern char *yytext; /* Generated by lex */
extern int yylineno; /* Generated by lex */
extern void nows P((void)); /* Declared in llama.lex. */
extern void ws P((void)); /* Declared in llama.lex. */
#define YYSTYPE char* /* Value-stack type. */
%}
%token ACTION /* {str} */
%token CODE_BLOCK /* %{ ... %} */
%token COLON /* : */
%token END_OPT /* ] ]* */
%token FIELD /* <name> */
%token LEFT /* %left */
%token NAME /* name */
%token NONASSOC /* %nonassoc */
%token OR /* | */
%token OTHER /* anything else (USED only in llpar.c) */
%token PREC /* %prec */
%token RIGHT /* %right */
%token SEMI /* ; */
%token SEPARATOR /* %% */
%token START /* %start */
%token START_OPT /* [ */
%token SYNCH /* %synch */
%token TERM_SPEC /* %term or %token */
%token TYPE /* %type */
%token PERCENT_UNION /* %union */
%token WHITESPACE /* 0 <= c <= ' ' (USED only in llpar.c) */
%synch SEMI OR
%%
spec : defs SEPARATOR { first_sym(); } rules end
;
end : {ws();} SEPARATOR
| /* empty */
;
defs : SYNCH snames defs
| PERCENT_UNION ACTION { union_def( yytext ); } defs
| TYPE fnames {new_field("");} defs
| TERM_SPEC { new_lev ( 0 ); } tnames {new_field("");} defs
| LEFT { new_lev ('l'); } pnames {new_field("");} defs
| RIGHT { new_lev ('r'); } pnames {new_field("");} defs
| NONASSOC { new_lev ('n'); } pnames {new_field("");} defs
| CODE_BLOCK /* the block is copied out by yylex */ defs
| START
{
lerror(NONFATAL,"%%start not supported by occs. First " );
lerror(NOHDR, "production is the start production\n." );
}
opt_names defs
| /* empty */
;
fnames : NAME { new_nonterm (yytext,0); } fnames
| FIELD { new_field (yytext); } fnames
| /* empty */
;
tnames : NAME { make_term(yytext); } tnames
| FIELD { new_field(yytext); } tnames
| /* empty */
;
pnames : NAME { prec_list(yytext); } pnames
| FIELD { new_field(yytext); } pnames
| /* empty */
;
opt_names : NAME opt_names
| /* empty */
;
snames : NAME { add_synch(yytext); } snames | /* empty */ ;
rules : rule rules
| /* empty */
;
rule : NAME { new_nonterm(yytext,1); } COLON right_sides
| FIELD { new_nonterm(yytext,1); } COLON right_sides
;
right_sides : { new_rhs(); } rhs end_rhs
;
end_rhs : OR right_sides
| SEMI
;
rhs : NAME { add_to_rhs(yytext, 0 ); } rhs
| FIELD { add_to_rhs(yytext, 0 ); } rhs
| ACTION { add_to_rhs(yytext, start_action()); } rhs
| PREC NAME { prec (yytext ); } rhs
| START_OPT { start_opt( yytext ); }
rhs END_OPT { end_opt ( yytext ); }
rhs
| /* empty */
;
%%
/* Support routines for the llama parser. The arguments must be declared void*
* to get them to match the prototypes in l.h. They are really ponters to
* yyvstypes, though.
*/
void yy_init_llama( tovs )
void *tovs;
{
((yyvstype *)tovs)->left = ((yyvstype *)tovs)->right = "" ;
}
#ifdef __TURBOC__
#pragma argsused
#endif
char *yypstk(tovs, tods)
void *tovs;
char *tods;
{
static char buf[128];
yyvstype *vs = (yyvstype *)tovs;
if( *vs->left || *vs->right )
{
sprintf(buf,"[%s,%s]", vs->left, vs->right);
return buf;
}
else
return "";
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -