本文介绍了野牛转移而不是减少.减少/减少错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以用我的语言写

a = 1

b = 2
if true { } else { }
if true { } **Here is the problem**
else {}

我的语法不支持语句之间的换行符. else只能与if一起使用.当我在规则中添加optionalNL

My grammer doesnt support newlines between statements. An else can only be used with an if. When i add optionalNL in my rule

IfExpr:
  IF rval optionalNL codeBlock optionalNL ELSE codeBlock
| IF rval optionalNL codeBlock

else之前的optionalNL导致3减少/减少.原因是它可以使用IfExpr中的第二条规则来减少,也可以减少到允许在表达式之间使用许多换行符的exprLoop.

The optionalNL before the else causes 3 reduce/reduce. Reason is it can reduce using the 2nd rule in IfExpr or reduce to exprLoop where it allows many newlines between expressions.

无论我做什么(我尝试在optionalNL和ELSE之前写%prec),它总是会减少为exprLoop,在这种情况下,野牛会给我其他方面的Synax错误.我如何告诉野牛在这一点上转移(到其他可选NL)而不是减少? (以exprLoop导致其他错误).

No matter what i do (i tried writing %prec before optionalNL and ELSE) it always reduces to exprLoop which cases bison to give me a synax error on else. How do i tell bison to shift at this point (to optionalNL else) instead of reduce? (to exprLoop causing else to be an error).

要测试的示例文件

%%
program:
      exprLoop;
exprLoop:
      exprLoop2 expr
    | exprLoop2
exprLoop2:
    | exprLoop2 expr EOS
    | exprLoop2 EOS
    ;
expr:
      'i' Var optEOS '{' '}'
    | 'i' Var optEOS '{' '}' optEOS 'e' '{' '}'
EOS: '\n'   ;
Var: 'v';
optEOS: | optEOS EOS

%%

//this can be added to the lex file
[iev]                   { return *yytext; }

y.output http://www.pastie.org/707448

y.output http://www.pastie.org/707448

替代.y和输出.您可以看到\ n,并且不知道要减少规则还是继续前进.我更改规则的顺序以获取不同的结果.但是它要么总是期望\ n,要么总是期望另一个,因此一个规则总是最终被忽略. 州15

Alternative .y and output. You can see it looking ahead seeing a \n and doesnt know to reduce the rule or keep going. I change change the order of the rules to get different results. But it either always expects a \n or always expects an else thus one rule always end up being ignore. state 15

    9 expr: 'i' Var optEOS '{' '}' .  [$end, '\n']
   10     | 'i' Var optEOS '{' '}' . 'e' '{' '}'
   11     | 'i' Var optEOS '{' '}' . '\n' 'e' '{' '}'

    'e'   shift, and go to state 16
    '\n'  shift, and go to state 17

    '\n'      [reduce using rule 9 (expr)]
    $default  reduce using rule 9 (expr)

感谢Kinopiko的他的回答

Thanks to Kinopiko for his answer

我将他的代码更改为没有冲突,然后致力于使其更加灵活.这是我的文件

I changed his code to have no conflicts then worked on making it more flexible. Heres are my files

test.y

%{
#include <stdio.h>
%}

%%

program: expr                                   { printf ("First expr\n"); }
       | program expr                           { printf ("Another expr\n"); }

expr:
      if optEOS                                 { printf ("IF only\n"); }
    | if optEOS else optEOS                     { printf ("IF/ELSE\n"); }

if:   'i' Var optEOS '{' optEOS '}'
else: 'e' optEOS     '{' optEOS '}'
EOS:  '\n'
Var:  'v'
optEOS:
          | EOS optEOS                          { ;}//printf ("many EOS\n"); }
%%

int main(int argc, char **argv)
{
    int i;

    printf("starting\n");

    if(argc < 2) {
        printf("Reading from stdin\n");
        yyparse();
        return 0;
    }
    for(i = 1; i < argc; i++) {
        FILE *f;
        char fn[260];
        sprintf(fn, "./%s", argv[i]);
        f = fopen(fn, "r");
        if(!f) {
            perror(argv[i]);
            return (1);
        }
        printf("Running '%s'\n", argv[i]);
        yyrestart(f);
        yyparse();
        fclose(f);
        printf("done\n");
    }
    return 0;
}

test.y

%{
#include <stdio.h>
#include "y.tab.h"
%}
%option noyywrap
%%
[ \t]               { }
\n                  { return *yytext; }
.                   { return *yytext; }
%%
int yyerror ()
{
    printf ("syntax error\n");
    exit (1);
}

编译后自动运行的测试文件

a test file that auto ran after compiling

i v { }
i v { }
e { }
i v { }

e { }
i v {
} e {
 }
i v { }


i v { } i v { } e { }

i v
{ } i v { } e { } i v { } e {
} i v {
 } e
{ }

推荐答案

我不太了解您的问题,所以我从头开始:

I don't understand your problem very well, so I started from scratch:

这是我的语法:

%{
#include <stdio.h>
%}

%%

program: expr                                   { printf ("First expr\n") }
       | program EOS                            { printf ("Ate an EOS\n") }
       | program expr                           { printf ("Another expr\n") }

expr:
      ifeos                                     { printf ("IF only\n"); }
    | ifelse                                    { printf ("IF/ELSE\n"); }

ifelse: ifeos else
      | if else

ifeos: if EOS
     | ifeos EOS

if:   'i' Var optEOS '{' '}'
else: 'e' '{' '}'
EOS:  '\n'
Var:  'v'
optEOS:
          | EOS optEOS                          { printf ("many EOS\n") }
%%

这是词法分析器:

%{
#include <stdio.h>
#include "1763243.tab.h"
%}
%option noyywrap
%%
[iev\{\}\n]                  { return *yytext; }
\x20                         { }
%%
int yyerror ()
{
    printf ("syntax error\n");
    exit (1);
}
int main () {
    yyparse ();
}

以下是一些测试输入:


i v { }
i v { }
e { }
i v { }

e { }
i v { } e { }
i v { }

以下是输出:


IF only
First expr
IF/ELSE
Another expr
Ate an EOS
IF/ELSE
Another expr
Ate an EOS
IF/ELSE
Another expr
Ate an EOS
IF only
Another expr

还有移位/减少冲突.

这篇关于野牛转移而不是减少.减少/减少错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 04:26