⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.lma

📁 its about compiler for LL1 and LR
💻 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 + -