%{
-/* $OpenBSD: gram.y,v 1.6 1996/10/23 22:37:52 niklas Exp $ */
-/* $NetBSD: gram.y,v 1.9 1996/08/31 21:15:07 mycroft Exp $ */
+/* $OpenBSD: gram.y,v 1.7 1997/01/18 02:24:14 briggs Exp $ */
+/* $NetBSD: gram.y,v 1.12 1996/11/11 23:54:17 gwr Exp $ */
/*
* Copyright (c) 1992, 1993
* from: @(#)gram.y 8.1 (Berkeley) 6/6/93
*/
-#include <sys/param.h>
#include <sys/types.h>
-#include <sys/stat.h>
+#include <sys/param.h>
#include <ctype.h>
-#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int include __P((const char *, int));
void yyerror __P((const char *));
int yylex __P((void));
-extern const char *lastfile;
static struct config conf; /* at most one active at a time */
#define fx_and(e1, e2) new0(NULL, NULL, e1, FX_AND, e2)
#define fx_or(e1, e2) new0(NULL, NULL, e1, FX_OR, e2)
-static void setupdirs __P((void));
static void cleanup __P((void));
static void setmachine __P((const char *, const char *));
-static void setmaxpartitions __P((int));
+static void check_maxpart __P((void));
%}
%token AND AT ATTACH BUILD COMPILE_WITH CONFIG DEFINE DEVICE DISABLE DUMPS
%token ENDFILE XFILE FLAGS INCLUDE XMACHINE MAJOR MAKEOPTIONS MAXUSERS
%token MAXPARTITIONS MINOR ON OPTIONS PSEUDO_DEVICE ROOT SOURCE SWAP WITH
-%token <val> FFLAG NUMBER
+%token NEEDS_COUNT NEEDS_FLAG
+%token <val> NUMBER
%token <str> PATHNAME WORD
+%left '|'
+%left '&'
+
%type <list> fopts fexpr fatom
-%type <val> fflgs
+%type <val> fflgs fflag
%type <str> rule
%type <attr> attr
%type <devb> devbase
%type <val> major_minor signed_number npseudo
%type <val> flags_opt
-%left '|'
-%left '&'
-
%%
/*
* definition files (via the include() mechanism), followed by the
* configuration specification(s) proper. In effect, this is two
* separate grammars, with some shared terminals and nonterminals.
+ * Note that we do not have sufficient keywords to enforce any order
+ * between elements of "topthings" without introducing shift/reduce
+ * conflicts. Instead, check order requirements in the C code.
*/
Configuration:
- dirs hdrs machine_spec /* "machine foo" from machine descr. */
- dev_defs dev_eof /* ../../conf/devices */
- dev_defs dev_eof /* devices.foo */
- maxpart_spec dev_defs dev_eof /* ../../conf/devices */
+ topthings /* dirspecs, include "std.arch" */
+ machine_spec /* "machine foo" from machine descr. */
+ dev_defs dev_eof /* sys/conf/files */
+ dev_defs dev_eof /* sys/arch/${MACHINE_ARCH}/... */
+ dev_defs dev_eof /* sys/arch/${MACHINE}/... */
+ { check_maxpart(); }
specs; /* rest of machine description */
-dirs:
- dirspecs = { setupdirs(); };
-
-dirspecs:
- dirspecs dir |
+topthings:
+ topthings topthing |
/* empty */;
-dir:
- SOURCE PATHNAME = { if (!srcdir) srcdir = $2; } |
- BUILD PATHNAME = { if (!builddir) builddir = $2; } |
- '\n';
-
-hdrs:
- hdrs hdr |
- /* empty */;
-
-hdr:
- include |
+topthing:
+ SOURCE PATHNAME '\n' { if (!srcdir) srcdir = $2; } |
+ BUILD PATHNAME '\n' { if (!builddir) builddir = $2; } |
+ include '\n' |
'\n';
machine_spec:
- XMACHINE WORD = { setmachine($2,NULL); } |
- XMACHINE WORD WORD = { setmachine($2,$3); } |
- error = { stop("cannot proceed without machine specifier"); };
+ XMACHINE WORD '\n' { setmachine($2,NULL); } |
+ XMACHINE WORD WORD '\n' { setmachine($2,$3); } |
+ error { stop("cannot proceed without machine specifier"); };
dev_eof:
- ENDFILE = { enddefs(lastfile); checkfiles(); };
-
-maxpart_blanks:
- maxpart_blanks '\n' |
- /* empty */;
-
-maxpart_spec:
- maxpart_blanks MAXPARTITIONS NUMBER = { setmaxpartitions($3); } |
- error = { stop("cannot proceed without maxpartitions specifier"); };
+ ENDFILE { enddefs(); checkfiles(); };
/*
* Various nonterminals shared between the grammars.
*/
file:
- XFILE PATHNAME fopts fflgs rule = { addfile($2, $3, $4, $5); };
+ XFILE PATHNAME fopts fflgs rule { addfile($2, $3, $4, $5); };
/* order of options is important, must use right recursion */
fopts:
- fexpr = { $$ = $1; } |
- /* empty */ = { $$ = NULL; };
+ fexpr { $$ = $1; } |
+ /* empty */ { $$ = NULL; };
fexpr:
- fatom = { $$ = $1; } |
- '!' fatom = { $$ = fx_not($2); } |
- fexpr '&' fexpr = { $$ = fx_and($1, $3); } |
- fexpr '|' fexpr = { $$ = fx_or($1, $3); } |
- '(' fexpr ')' = { $$ = $2; };
+ fatom { $$ = $1; } |
+ '!' fatom { $$ = fx_not($2); } |
+ fexpr '&' fexpr { $$ = fx_and($1, $3); } |
+ fexpr '|' fexpr { $$ = fx_or($1, $3); } |
+ '(' fexpr ')' { $$ = $2; };
fatom:
- WORD = { $$ = fx_atom($1); };
+ WORD { $$ = fx_atom($1); };
fflgs:
- fflgs FFLAG = { $$ = $1 | $2; } |
- /* empty */ = { $$ = 0; };
+ fflgs fflag { $$ = $1 | $2; } |
+ /* empty */ { $$ = 0; };
+
+fflag:
+ NEEDS_COUNT { $$ = FI_NEEDSCOUNT; } |
+ NEEDS_FLAG { $$ = FI_NEEDSFLAG; };
rule:
- COMPILE_WITH WORD = { $$ = $2; } |
- /* empty */ = { $$ = NULL; };
+ COMPILE_WITH WORD { $$ = $2; } |
+ /* empty */ { $$ = NULL; };
include:
- INCLUDE WORD = { include($2, '\n'); };
+ INCLUDE WORD { include($2, 0); };
+
/*
* The machine definitions grammar.
/* empty */;
dev_def:
- one_def '\n' = { adepth = 0; } |
+ one_def '\n' { adepth = 0; } |
'\n' |
- error '\n' = { cleanup(); };
+ error '\n' { cleanup(); };
one_def:
file |
include |
- DEFINE WORD interface_opt = { (void)defattr($2, $3); } |
+ DEFINE WORD interface_opt { (void)defattr($2, $3); } |
DEVICE devbase interface_opt attrs_opt
- = { defdev($2, 0, $3, $4); } |
+ { defdev($2, 0, $3, $4); } |
ATTACH devbase AT atlist devattach_opt attrs_opt
- = { defdevattach($5, $2, $4, $6); } |
- MAXUSERS NUMBER NUMBER NUMBER = { setdefmaxusers($2, $3, $4); } |
- PSEUDO_DEVICE devbase attrs_opt = { defdev($2,1,NULL,$3); } |
+ { defdevattach($5, $2, $4, $6); } |
+ MAXUSERS NUMBER NUMBER NUMBER { setdefmaxusers($2, $3, $4); } |
+ MAXPARTITIONS NUMBER { maxpartitions = $2; } |
+ PSEUDO_DEVICE devbase attrs_opt { defdev($2,1,NULL,$3); } |
MAJOR '{' majorlist '}';
disable:
- DISABLE = { $$ = 1; } |
- /* empty */ = { $$ = 0; };
+ DISABLE { $$ = 1; } |
+ /* empty */ { $$ = 0; };
atlist:
- atlist ',' atname = { $$ = new_nx($3, $1); } |
- atname = { $$ = new_n($1); };
+ atlist ',' atname { $$ = new_nx($3, $1); } |
+ atname { $$ = new_n($1); };
atname:
- WORD = { $$ = $1; } |
- ROOT = { $$ = NULL; };
+ WORD { $$ = $1; } |
+ ROOT { $$ = NULL; };
devbase:
- WORD = { $$ = getdevbase($1); };
+ WORD { $$ = getdevbase($1); };
devattach_opt:
- WITH WORD = { $$ = getdevattach($2); } |
- /* empty */ = { $$ = NULL; };
+ WITH WORD { $$ = getdevattach($2); } |
+ /* empty */ { $$ = NULL; };
interface_opt:
- '{' loclist_opt '}' = { $$ = new_nx("", $2); } |
- /* empty */ = { $$ = NULL; };
+ '{' loclist_opt '}' { $$ = new_nx("", $2); } |
+ /* empty */ { $$ = NULL; };
loclist_opt:
- loclist = { $$ = $1; } |
- /* empty */ = { $$ = NULL; };
+ loclist { $$ = $1; } |
+ /* empty */ { $$ = NULL; };
/* loclist order matters, must use right recursion */
loclist:
- locdef ',' loclist = { ($$ = $1)->nv_next = $3; } |
- locdef = { $$ = $1; };
+ locdef ',' loclist { ($$ = $1)->nv_next = $3; } |
+ locdef { $$ = $1; };
/* "[ WORD locdefault ]" syntax may be unnecessary... */
locdef:
- WORD locdefault = { $$ = new_nsi($1, $2, 0); } |
- WORD = { $$ = new_nsi($1, NULL, 0); } |
- '[' WORD locdefault ']' = { $$ = new_nsi($2, $3, 1); };
+ WORD locdefault { $$ = new_nsi($1, $2, 0); } |
+ WORD { $$ = new_nsi($1, NULL, 0); } |
+ '[' WORD locdefault ']' { $$ = new_nsi($2, $3, 1); };
locdefault:
- '=' value = { $$ = $2; };
+ '=' value { $$ = $2; };
value:
- WORD = { $$ = $1; } |
- signed_number = { char bf[40];
+ WORD { $$ = $1; } |
+ signed_number { char bf[40];
(void)sprintf(bf, FORMAT($1), $1);
$$ = intern(bf); };
signed_number:
- NUMBER = { $$ = $1; } |
- '-' NUMBER = { $$ = -$2; };
+ NUMBER { $$ = $1; } |
+ '-' NUMBER { $$ = -$2; };
attrs_opt:
- ':' attrs = { $$ = $2; } |
- /* empty */ = { $$ = NULL; };
+ ':' attrs { $$ = $2; } |
+ /* empty */ { $$ = NULL; };
attrs:
- attrs ',' attr = { $$ = new_px($3, $1); } |
- attr = { $$ = new_p($1); };
+ attrs ',' attr { $$ = new_px($3, $1); } |
+ attr { $$ = new_p($1); };
attr:
- WORD = { $$ = getattr($1); };
+ WORD { $$ = getattr($1); };
majorlist:
majorlist ',' majordef |
majordef;
majordef:
- devbase '=' NUMBER = { setmajor($1, $3); };
+ devbase '=' NUMBER { setmajor($1, $3); };
/* empty */;
spec:
- config_spec '\n' = { adepth = 0; } |
+ config_spec '\n' { adepth = 0; } |
'\n' |
- error '\n' = { cleanup(); };
+ error '\n' { cleanup(); };
config_spec:
file |
include |
OPTIONS opt_list |
MAKEOPTIONS mkopt_list |
- MAXUSERS NUMBER = { setmaxusers($2); } |
- CONFIG conf sysparam_list = { addconf(&conf); } |
- PSEUDO_DEVICE WORD npseudo = { addpseudo($2, $3); } |
+ MAXUSERS NUMBER { setmaxusers($2); } |
+ CONFIG conf sysparam_list { addconf(&conf); } |
+ PSEUDO_DEVICE WORD npseudo { addpseudo($2, $3); } |
device_instance AT attachment disable locators flags_opt
- = { adddev($1, $3, $5, $6, $4); };
+ { adddev($1, $3, $5, $6, $4); };
mkopt_list:
mkopt_list ',' mkoption |
mkoption;
mkoption:
- WORD '=' value = { addmkoption($1, $3); }
+ WORD '=' value { addmkoption($1, $3); }
opt_list:
opt_list ',' option |
option;
option:
- WORD = { addoption($1, NULL); } |
- WORD '=' value = { addoption($1, $3); };
+ WORD { addoption($1, NULL); } |
+ WORD '=' value { addoption($1, $3); };
conf:
- WORD = { conf.cf_name = $1;
+ WORD { conf.cf_name = $1;
conf.cf_lineno = currentline();
conf.cf_root = NULL;
conf.cf_swap = NULL;
sysparam;
sysparam:
- ROOT on_opt dev_spec = { setconf(&conf.cf_root, "root", $3); } |
- SWAP on_opt swapdev_list = { setconf(&conf.cf_swap, "swap", $3); } |
- DUMPS on_opt dev_spec = { setconf(&conf.cf_dump, "dumps", $3); };
+ ROOT on_opt dev_spec { setconf(&conf.cf_root, "root", $3); } |
+ SWAP on_opt swapdev_list { setconf(&conf.cf_swap, "swap", $3); } |
+ DUMPS on_opt dev_spec { setconf(&conf.cf_dump, "dumps", $3); };
swapdev_list:
- dev_spec AND swapdev_list = { ($$ = $1)->nv_next = $3; } |
- dev_spec = { $$ = $1; };
+ dev_spec AND swapdev_list { ($$ = $1)->nv_next = $3; } |
+ dev_spec { $$ = $1; };
dev_spec:
- WORD = { $$ = new_si($1, NODEV); } |
- major_minor = { $$ = new_si(NULL, $1); };
+ WORD { $$ = new_si($1, NODEV); } |
+ major_minor { $$ = new_si(NULL, $1); };
major_minor:
- MAJOR NUMBER MINOR NUMBER = { $$ = makedev($2, $4); };
+ MAJOR NUMBER MINOR NUMBER { $$ = makedev($2, $4); };
on_opt:
ON | /* empty */;
npseudo:
- NUMBER = { $$ = $1; } |
- /* empty */ = { $$ = 1; };
+ NUMBER { $$ = $1; } |
+ /* empty */ { $$ = 1; };
device_instance:
- WORD '*' = { $$ = starref($1); } |
- WORD = { $$ = $1; };
+ WORD '*' { $$ = starref($1); } |
+ WORD { $$ = $1; };
attachment:
- ROOT = { $$ = NULL; } |
- WORD '?' = { $$ = wildref($1); } |
- WORD = { $$ = $1; };
+ ROOT { $$ = NULL; } |
+ WORD '?' { $$ = wildref($1); } |
+ WORD { $$ = $1; };
locators:
- locators locator = { ($$ = $2)->nv_next = $1; } |
- /* empty */ = { $$ = NULL; };
+ locators locator { ($$ = $2)->nv_next = $1; } |
+ /* empty */ { $$ = NULL; };
locator:
- WORD value = { $$ = new_ns($1, $2); } |
- WORD '?' = { $$ = new_ns($1, NULL); };
+ WORD value { $$ = new_ns($1, $2); } |
+ WORD '?' { $$ = new_ns($1, NULL); };
flags_opt:
- FLAGS NUMBER = { $$ = $2; } |
- /* empty */ = { $$ = 0; };
+ FLAGS NUMBER { $$ = $2; } |
+ /* empty */ { $$ = 0; };
%%
error("%s", s);
}
-/*
- * Verify/create builddir if necessary, change to it, and verify srcdir.
- */
-static void
-setupdirs()
-{
- struct stat st;
- char *prof;
-
- /* srcdir must be specified if builddir is not specified or if
- * no configuration filename was specified. */
- if ((builddir || strcmp(defbuilddir, ".") == 0) && !srcdir)
- stop("source directory must be specified");
-
- if (srcdir == NULL)
- srcdir = "../../../..";
- if (builddir == NULL)
- builddir = defbuilddir;
-
- if (stat(builddir, &st) != 0) {
- if (mkdir(builddir, 0777)) {
- (void)fprintf(stderr, "config: cannot create %s: %s\n",
- builddir, strerror(errno));
- exit(2);
- }
- } else if (!S_ISDIR(st.st_mode)) {
- (void)fprintf(stderr, "config: %s is not a directory\n",
- builddir);
- exit(2);
- }
- if (chdir(builddir) != 0) {
- (void)fprintf(stderr, "config: cannot change to %s\n",
- builddir);
- exit(2);
- }
- if (stat(srcdir, &st) != 0 || !S_ISDIR(st.st_mode)) {
- (void)fprintf(stderr, "config: %s is not a directory\n",
- srcdir);
- exit(2);
- }
-}
-
/*
* Cleanup procedure after syntax error: release any nvlists
* allocated during parsing the current line.
}
static void
-setmaxpartitions(n)
- int n;
+check_maxpart()
{
-
- maxpartitions = n;
+ if (maxpartitions <= 0) {
+ stop("cannot proceed without maxpartitions specifier");
+ }
}
%{
-/* $OpenBSD: scan.l,v 1.6 1996/10/23 22:37:59 niklas Exp $ */
-/* $NetBSD: scan.l,v 1.7 1996/08/31 21:15:13 mycroft Exp $ */
+/* $OpenBSD: scan.l,v 1.7 1997/01/18 02:24:18 briggs Exp $ */
+/* $NetBSD: scan.l,v 1.11 1996/11/13 18:42:18 gwr Exp $ */
/*
* Copyright (c) 1992, 1993
const char *yyfile;
const char *lastfile;
-int include __P((const char *, int));
-
/*
* Data for returning to previous files from include files.
*/
YY_BUFFER_STATE in_buf; /* previous lex state */
const char *in_fname; /* previous file name */
int in_lineno; /* previous line number */
- int in_preveof; /* previous eoftoken */
+ int in_ateof; /* token to insert at EOF */
};
static struct incl *incl;
-static int eoftoken; /* current EOF token */
-static void endinclude __P((void));
+static int endinclude __P((void));
#define yywrap() 1
%}
-PATH [-/A-Za-z0-9_.]*[./][-/A-Za-z0-9_.]*
+PATH [A-Za-z_0-9]*[./][-A-Za-z_0-9./]*
WORD [A-Za-z_][-A-Za-z_0-9]*
%%
+ /* Local variables for yylex() */
+ int tok;
+
+and return AND;
+at return AT;
+attach return ATTACH;
+build return BUILD;
+compile-with return COMPILE_WITH;
+config return CONFIG;
+define return DEFINE;
+device return DEVICE;
+disable return DISABLE;
+dumps return DUMPS;
+file return XFILE;
+flags return FLAGS;
+include return INCLUDE;
+machine return XMACHINE;
+major return MAJOR;
+makeoptions return MAKEOPTIONS;
+maxpartitions return MAXPARTITIONS;
+maxusers return MAXUSERS;
+minor return MINOR;
+needs-count return NEEDS_COUNT;
+needs-flag return NEEDS_FLAG;
+on return ON;
+options return OPTIONS;
+option return OPTIONS;
+pseudo-device return PSEUDO_DEVICE;
+root return ROOT;
+source return SOURCE;
+swap return SWAP;
+with return WITH;
+
+{PATH} {
+ yylval.str = intern(yytext);
+ return PATHNAME;
+ }
+{WORD} {
+ yylval.str = intern(yytext);
+ return WORD;
+ }
- /* plain keywords */
-and { return AND; }
-at { return AT; }
-attach { return ATTACH; }
-build { return BUILD; }
-compile-with { return COMPILE_WITH; }
-config { return CONFIG; }
-define { return DEFINE; }
-device { return DEVICE; }
-disable { return DISABLE; }
-dumps { return DUMPS; }
-flags { return FLAGS; }
-file { return XFILE; }
-include { return INCLUDE; }
-machine { return XMACHINE; }
-major { return MAJOR; }
-makeoptions { return MAKEOPTIONS; }
-maxusers { return MAXUSERS; }
-maxpartitions { return MAXPARTITIONS; }
-minor { return MINOR; }
-on { return ON; }
-options { return OPTIONS; }
-option { return OPTIONS; }
-"pseudo-device" { return PSEUDO_DEVICE; }
-root { return ROOT; }
-source { return SOURCE; }
-swap { return SWAP; }
-with { return WITH; }
-
- /* keywords with values */
-needs-count { yylval.val = FI_NEEDSCOUNT; return FFLAG; }
-needs-flag { yylval.val = FI_NEEDSFLAG; return FFLAG; }
-
- /* all the rest */
-{PATH} { yylval.str = intern(yytext); return PATHNAME; }
-{WORD} { yylval.str = intern(yytext); return WORD; }
-
-\"([^"]|\\\")*/\" {
+\"([^"\n]|\\\")+ {
+ tok = input(); /* eat closing quote */
+ if (tok != '"') {
+ error("closing quote missing\n");
+ unput(tok);
+ }
yylval.str = intern(yytext + 1);
- (void)input(); /* eat closing quote */
return WORD;
}
0[0-7]* {
yylval.val = strtol(yytext, NULL, 10);
return NUMBER;
}
-\n/[ \t] {
+\n[ \t] {
+ /*
+ * Note: newline followed by whitespace is always a
+ * continuation of the previous line, so do NOT
+ * return a token in this case.
+ */
yyline++;
}
\n {
return '\n';
}
#.* { /* ignored (comment) */; }
-[ \t]* { /* ignored (white space) */; }
+[ \t]+ { /* ignored (white space) */; }
. { return yytext[0]; }
<<EOF>> {
- int tok;
-
- tok = eoftoken;
- eoftoken = YY_NULL;
- if (incl != NULL)
- endinclude();
- return (tok);
+ if (incl == NULL)
+ return YY_NULL;
+ tok = endinclude();
+ if (tok)
+ return tok;
+ /* otherwise continue scanning */
}
%%
return (-1);
yyfile = conffile = fname;
yyline = 1;
- eoftoken = YY_NULL;
return (0);
}
* Open the named file for inclusion at the current point. Returns 0 on
* success (file opened and previous state pushed), nonzero on failure
* (fopen failed, complaint made). The `ateof' parameter controls the
- * token to be returned at the end of the include file (typically '\n'
- * or ENDFILE).
+ * token to be inserted at the end of the include file (i.e. ENDFILE).
+ * If ateof == 0 then nothing is inserted.
*/
int
include(fname, ateof)
const char *fname;
int ateof;
{
- register FILE *fp;
- register struct incl *in;
+ FILE *fp;
+ struct incl *in;
char *s;
+ static int havedirs;
+
+ if (havedirs == 0) {
+ havedirs = 1;
+ setupdirs();
+ }
/* Kludge until files.* files are fixed. */
if (strncmp(fname, "../../../", 9) == 0)
in->in_buf = YY_CURRENT_BUFFER;
in->in_fname = yyfile;
in->in_lineno = yyline;
- in->in_preveof = eoftoken;
+ in->in_ateof = ateof;
incl = in;
yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE));
yyfile = intern(s);
yyline = 1;
- eoftoken = ateof;
free(s);
return (0);
}
/*
* Terminate the most recent inclusion.
*/
-static void
+static int
endinclude()
{
- register struct incl *in;
+ struct incl *in;
+ int ateof;
if ((in = incl) == NULL)
panic("endinclude");
yy_switch_to_buffer(in->in_buf);
yyfile = in->in_fname;
yyline = in->in_lineno;
- eoftoken = in->in_preveof;
+ ateof = in->in_ateof;
free(in);
+
+ return (ateof);
}
/*