rc: move newline handling into parser
This commit is contained in:
parent
47d4646eeb
commit
3caf5c238a
6 changed files with 67 additions and 24 deletions
|
|
@ -9,6 +9,8 @@ fi
|
||||||
|
|
||||||
for i in $files
|
for i in $files
|
||||||
do
|
do
|
||||||
|
if ! diff <(./o.rc -DY $i 2>&1) <(./o.rc -D $i 2>&1); then
|
||||||
echo '#' $i
|
echo '#' $i
|
||||||
diff <(./o.rc -DY $i 2>&1) <(./o.rc -D $i 2>&1)
|
exit 1
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
|
|
||||||
|
|
@ -102,15 +102,17 @@ pprompt(void)
|
||||||
doprompt = 0;
|
doprompt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
skipwhite(void)
|
skipwhite(void)
|
||||||
{
|
{
|
||||||
int c;
|
int c, skipped;
|
||||||
|
skipped = 0;
|
||||||
for(;;){
|
for(;;){
|
||||||
c = nextc();
|
c = nextc();
|
||||||
/* Why did this used to be if(!inquote && c=='#') ?? */
|
/* Why did this used to be if(!inquote && c=='#') ?? */
|
||||||
if(c=='#'){
|
if(c=='#'){
|
||||||
incomm = 1;
|
incomm = 1;
|
||||||
|
skipped = 1;
|
||||||
for(;;){
|
for(;;){
|
||||||
c = nextc();
|
c = nextc();
|
||||||
if(c=='\n' || c==EOF) {
|
if(c=='\n' || c==EOF) {
|
||||||
|
|
@ -120,9 +122,12 @@ skipwhite(void)
|
||||||
advance();
|
advance();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(c==' ' || c=='\t')
|
if(c==' ' || c=='\t') {
|
||||||
|
skipped = 1;
|
||||||
advance();
|
advance();
|
||||||
else return;
|
}
|
||||||
|
else
|
||||||
|
return skipped;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -210,7 +215,8 @@ yylex(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inquote = 0;
|
inquote = 0;
|
||||||
skipwhite();
|
if(skipwhite() && flag['Z'])
|
||||||
|
return SP;
|
||||||
switch(c = advance()){
|
switch(c = advance()){
|
||||||
case EOF:
|
case EOF:
|
||||||
lastdol = 0;
|
lastdol = 0;
|
||||||
|
|
@ -231,6 +237,7 @@ yylex(void)
|
||||||
case '&':
|
case '&':
|
||||||
lastdol = 0;
|
lastdol = 0;
|
||||||
if(nextis('&')){
|
if(nextis('&')){
|
||||||
|
if(flag['Y'])
|
||||||
skipnl();
|
skipnl();
|
||||||
strcpy(tok, "&&");
|
strcpy(tok, "&&");
|
||||||
return ANDAND;
|
return ANDAND;
|
||||||
|
|
@ -240,6 +247,7 @@ yylex(void)
|
||||||
case '|':
|
case '|':
|
||||||
lastdol = 0;
|
lastdol = 0;
|
||||||
if(nextis(c)){
|
if(nextis(c)){
|
||||||
|
if(flag['Y'])
|
||||||
skipnl();
|
skipnl();
|
||||||
strcpy(tok, "||");
|
strcpy(tok, "||");
|
||||||
return OROR;
|
return OROR;
|
||||||
|
|
@ -329,7 +337,7 @@ yylex(void)
|
||||||
}
|
}
|
||||||
*w='\0';
|
*w='\0';
|
||||||
yylval.tree = t;
|
yylval.tree = t;
|
||||||
if(t->type==PIPE)
|
if(t->type==PIPE && flag['Y'])
|
||||||
skipnl();
|
skipnl();
|
||||||
if(t->type==REDIR) {
|
if(t->type==REDIR) {
|
||||||
skipwhite();
|
skipwhite();
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,14 @@ static tree* words(int tok, int *ptok);
|
||||||
|
|
||||||
static jmp_buf yyjmp;
|
static jmp_buf yyjmp;
|
||||||
|
|
||||||
|
static int
|
||||||
|
dropnl(int tok)
|
||||||
|
{
|
||||||
|
while(tok == '\n')
|
||||||
|
tok = yylex();
|
||||||
|
return tok;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
syntax(int tok)
|
syntax(int tok)
|
||||||
{
|
{
|
||||||
|
|
@ -191,13 +199,11 @@ cmd(int tok, int *ptok)
|
||||||
tok = yylex();
|
tok = yylex();
|
||||||
if(tok == NOT) {
|
if(tok == NOT) {
|
||||||
t1 = yylval.tree;
|
t1 = yylval.tree;
|
||||||
skipnl();
|
t2 = cmd(dropnl(yylex()), ptok);
|
||||||
t2 = cmd(yylex(), ptok);
|
|
||||||
return mung1(t1, t2);
|
return mung1(t1, t2);
|
||||||
}
|
}
|
||||||
t2 = paren(tok);
|
t2 = paren(tok);
|
||||||
skipnl();
|
t3 = cmd(dropnl(yylex()), ptok);
|
||||||
t3 = cmd(yylex(), ptok);
|
|
||||||
return mung2(t1, t2, t3);
|
return mung2(t1, t2, t3);
|
||||||
|
|
||||||
case FOR:
|
case FOR:
|
||||||
|
|
@ -224,8 +230,7 @@ cmd(int tok, int *ptok)
|
||||||
syntax(tok);
|
syntax(tok);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
skipnl();
|
t4 = cmd(dropnl(yylex()), ptok);
|
||||||
t4 = cmd(yylex(), ptok);
|
|
||||||
return mung3(t1, t2, t3, t4);
|
return mung3(t1, t2, t3, t4);
|
||||||
|
|
||||||
case WHILE:
|
case WHILE:
|
||||||
|
|
@ -233,16 +238,14 @@ cmd(int tok, int *ptok)
|
||||||
// {$$=mung2($1, $2, $4);}
|
// {$$=mung2($1, $2, $4);}
|
||||||
t1 = yylval.tree;
|
t1 = yylval.tree;
|
||||||
t2 = paren(yylex());
|
t2 = paren(yylex());
|
||||||
skipnl();
|
t3 = cmd(dropnl(yylex()), ptok);
|
||||||
t3 = cmd(yylex(), ptok);
|
|
||||||
return mung2(t1, t2, t3);
|
return mung2(t1, t2, t3);
|
||||||
|
|
||||||
case SWITCH:
|
case SWITCH:
|
||||||
// | SWITCH word {skipnl();} brace
|
// | SWITCH word {skipnl();} brace
|
||||||
// {$$=tree2(SWITCH, $2, $4);}
|
// {$$=tree2(SWITCH, $2, $4);}
|
||||||
t1 = yyword(yylex(), &tok);
|
t1 = yyword(yylex(), &tok);
|
||||||
while(tok == '\n')
|
tok = dropnl(tok); // doesn't work in yacc grammar but works here!
|
||||||
tok = yylex();
|
|
||||||
t2 = brace(tok);
|
t2 = brace(tok);
|
||||||
*ptok = yylex();
|
*ptok = yylex();
|
||||||
return tree2(SWITCH, t1, t2);
|
return tree2(SWITCH, t1, t2);
|
||||||
|
|
@ -261,7 +264,7 @@ cmd2(int tok, int *ptok)
|
||||||
t1 = cmd3(tok, &tok);
|
t1 = cmd3(tok, &tok);
|
||||||
while(tok == ANDAND || tok == OROR) {
|
while(tok == ANDAND || tok == OROR) {
|
||||||
op = tok;
|
op = tok;
|
||||||
t2 = cmd3(yylex(), &tok);
|
t2 = cmd3(dropnl(yylex()), &tok);
|
||||||
t1 = tree2(op, t1, t2);
|
t1 = tree2(op, t1, t2);
|
||||||
}
|
}
|
||||||
*ptok = tok;
|
*ptok = tok;
|
||||||
|
|
@ -277,7 +280,7 @@ cmd3(int tok, int *ptok)
|
||||||
t1 = cmd4(tok, &tok);
|
t1 = cmd4(tok, &tok);
|
||||||
while(tok == PIPE) {
|
while(tok == PIPE) {
|
||||||
t2 = yylval.tree;
|
t2 = yylval.tree;
|
||||||
t3 = cmd4(yylex(), &tok);
|
t3 = cmd4(dropnl(yylex()), &tok);
|
||||||
t1 = mung2(t2, t1, t3);
|
t1 = mung2(t2, t1, t3);
|
||||||
}
|
}
|
||||||
*ptok = tok;
|
*ptok = tok;
|
||||||
|
|
|
||||||
|
|
@ -244,6 +244,9 @@ pcmdu(io *f, tree *t) /* unambiguous */
|
||||||
pfmt(f, "[%d]", t->fd0);
|
pfmt(f, "[%d]", t->fd0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if(t->rtype == HERE)
|
||||||
|
pfmt(f, "HERE %u)", c1);
|
||||||
|
else
|
||||||
pfmt(f, "%u %u)", c0, c1);
|
pfmt(f, "%u %u)", c0, c1);
|
||||||
break;
|
break;
|
||||||
case '=':
|
case '=':
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
%term FOR IN WHILE IF NOT TWIDDLE BANG SUBSHELL SWITCH FN
|
%term FOR IN WHILE IF NOT TWIDDLE BANG SUBSHELL SWITCH FN SP
|
||||||
%term WORD REDIR REDIRW DUP PIPE SUB
|
%term WORD REDIR REDIRW DUP PIPE SUB
|
||||||
%term SIMPLE ARGLIST WORDS BRACE PAREN PCMD PIPEFD /* not used in syntax */
|
%term SIMPLE ARGLIST WORDS BRACE PAREN PCMD PIPEFD /* not used in syntax */
|
||||||
/* operator priorities -- lowest first */
|
/* operator priorities -- lowest first */
|
||||||
|
|
|
||||||
|
|
@ -36,3 +36,30 @@ $#$x
|
||||||
x for in while if not ~ ! @ switch fn
|
x for in while if not ~ ! @ switch fn
|
||||||
x not$y
|
x not$y
|
||||||
a;b;c
|
a;b;c
|
||||||
|
if(x)
|
||||||
|
y
|
||||||
|
if(x)
|
||||||
|
{
|
||||||
|
y
|
||||||
|
}
|
||||||
|
if not
|
||||||
|
z
|
||||||
|
for(x)
|
||||||
|
y
|
||||||
|
for(x in y)
|
||||||
|
z
|
||||||
|
while(x)
|
||||||
|
y
|
||||||
|
# yacc doesn't accept a newline before the brace
|
||||||
|
# even though the rule is written as if it would
|
||||||
|
switch x {
|
||||||
|
}
|
||||||
|
switch (x) {
|
||||||
|
}
|
||||||
|
z
|
||||||
|
x &&
|
||||||
|
y
|
||||||
|
x ||
|
||||||
|
y
|
||||||
|
x |
|
||||||
|
y
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue