标签: yacc

使用Flex(lex)和Bison(yacc)处理错误

来自"野牛手册":

在一个简单的交互式命令解析器中,每个输入都是一行,允许yyparse在出错时返回1并让调用者在发生这种情况时忽略输入行的其余部分(然后再次调用yyparse)就足够了.

这几乎是我想要的,但我无法上班.基本上,我想在flex中检测和出错,如果检测到错误,让Bison丢弃整行.我现在所拥有的,是不是很正常,因为我的命令仍然执行:

kbsh: ls '/home
Error: Unterminated Single Quote
admin  kbrandt  tempuser
syntax error
kbsh: 
Run Code Online (Sandbox Code Playgroud)

在我的Bison文件中:

commands:
     /*Empty*/ { prompt(); } |
     command { prompt(); }
    ;

command:
    error {return 1; } |
    chdir_command |
    pwd_command |
    exit_command |
    WORD arg_list {
        execute_command($1, $2);
        //printf("%s, %s\n", $1, $2); 
    } |
    WORD { execute_command($1, NULL); }
    ;
Run Code Online (Sandbox Code Playgroud)

在我的Flex中:

'   {BEGIN inQuote; }

<inQuote>\n {printf("Error: Unterminated Single Quote\n"); BEGIN(0); return(ERROR);}
Run Code Online (Sandbox Code Playgroud)

c yacc lex bison flex-lexer

2
推荐指数
1
解决办法
3816
查看次数

如何在YACC中解决此Shift/Reduce冲突

我有这样的语法:

"匹配一个或多个rule1,其中rule1是一个或多个rule2,其中rule2是一个或多个rule3等,每个由换行符分隔".请看下面的例子.

start:   rule1_list
      ;

rule1_list:   rule1
           |  rule1_list NEWLINE rule1
            ;

rule1:   rule2
     |   rule2 NEWLINE rule3_list
      ;

rule2:   TERMINAL2
      ;

rule3_list:   rule3
          |   rule3_list NEWLINE rule3
          ;

rule3 :  TERMINAL3
      ;
Run Code Online (Sandbox Code Playgroud)

我这样做了转换/减少冲突,我怎样才能改变语法来停止?基本上它需要在新行之后进行分支,并查看下一个是TERMINAL2还是TERMINAL3.

c c++ parsing yacc bison

2
推荐指数
1
解决办法
4943
查看次数

野牛转移而非减少.减少/减少错误

用我的语言我可以写

a = 1

b = 2
if true { } else { }
if true { } **Here is the problem**
else {}
Run Code Online (Sandbox Code Playgroud)

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

IfExpr:
  IF rval optionalNL codeBlock optionalNL ELSE codeBlock
| IF rval optionalNL codeBlock
Run Code Online (Sandbox Code Playgroud)

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

无论我做什么(我尝试在OptionalNL和ELSE之前编写%prec)它总是减少到exprLoop,哪些情况下bison给我一个关于else的synax错误.我怎么告诉野牛在这一点上转移(到OptionalNL其他)而不是减少?(exprLoop导致else成为错误).

用于测试的示例文件

%%
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: …
Run Code Online (Sandbox Code Playgroud)

yacc bison reduce-reduce-conflict

2
推荐指数
1
解决办法
1123
查看次数

flex中数据类型的问题

我有个问题.

我正在编写一个flex程序,我正在使用这段代码:

%union {

    int entero;

    char *cadena;

    TipoDato tipo;

}
Run Code Online (Sandbox Code Playgroud)

此代码适用于我的数据类型.

我想评估下一行:expresion SUM expresion其中SUM是evaluate的运算和,例如69 + 60

当我写这个

if (($1.tipo == ENT) && ($3.tipo == ENT)){

           $$.tipo = ENT;

} else if (($1.tipo == CADEN) && ($3.tipo == CADEN)) {

     $$.tipo = CADEN;

     } else {

          printf ("Error en la suma: Tipos de datos incompatibles Revise los tipos\n");

          yyerror(parser);

}
Run Code Online (Sandbox Code Playgroud)

我有下一个错误

../src/buggy.y:350.37-38:$ 1 de`expresion'no tiene tipo declarado

../src/buggy.y:351.28-29:$ 1 de`expresion'no tiene tipo declarado

buggy.tab.c:在函数'yyparse'中:

buggy.tab.c:1646:警告:隐式声明函数'yylex'

../src/buggy.y:顶级:

lex.yy.c:1577:警告:'yyunput'已定义但未使用

lex.yy.c:1618:**警告:'input'已定义但未使用

Leyendo fichero'../ …

types yacc lex

2
推荐指数
1
解决办法
4768
查看次数

Python PLY解析器

我试图寻找这个问题的答案,但似乎找不到一个.我正在尝试使用PLY编写一个Python解析器,用于编写语言.我的BNF的简化版本如下所示:

statement-list -> statement ',' statement-list |
                 'print' expr

statement -> ident 'was' 'a' type |
             ident 'became' expr

type -> 'number' | 'letter'

expr -> factor |
       expr '+' factor |
       expr '-' factor

factor -> number | letter | ident
Run Code Online (Sandbox Code Playgroud)

其中数字和字母类似于int和char.

Yacc文档(http://www.dabeaz.com/ply/ply.html#ply_nn23)仅显示简单算术表达式的语法,其中明确了p [0]应该是什么.

def p_expression_plus(p):
   'expression : expression PLUS term'
    p[0] = p[1] + p[3]
Run Code Online (Sandbox Code Playgroud)

我的问题是我如何为我的BNF中的陈述清单做些什么?我有:

def p_statement_list_comma(p):
    'statement-list : statement COMMA statement-list'
Run Code Online (Sandbox Code Playgroud)

但我真的不确定下一步该放什么.任何帮助将非常感谢!

python parsing yacc ply

2
推荐指数
1
解决办法
4188
查看次数

野牛抱怨"冲突:1班/减少"

野牛抱怨"冲突:1班/减少".我看不出有什么不对.请帮忙.谢谢,

%token OR AND NUMBER
%%

search_condition:
        |       search_condition AND search_condition { printf(" AND "); }
        |       '(' search_condition ')'
        |       predicate
        ;

predicate:
                NUMBER { printf("%d\n", $1);  }
        ;
Run Code Online (Sandbox Code Playgroud)

yacc bison

2
推荐指数
1
解决办法
5470
查看次数

通过宏扩展跟踪原始行号

我正在开发一个有趣的汇编程序,用C,flex,bison编写.我想添加宏,包含和重复块,并考虑使用单独的预处理阶段解析器执行此操作.

我的问题是,我如何跟踪原始源代码行(和文件名)?这用于生成有用的错误消息,漂亮的打印和生成调试信息.

预处理完成后第二个解析器中的yylineno可能会在宏扩展后偏移,依此类推.

yacc lex compiler-theory dcpu-16

2
推荐指数
1
解决办法
265
查看次数

Lex:一个计算输入中单词的小程序

我对Lex非常陌生,这个问题的完整要求如下:

编写一个Lex输入文件,该文件将生成一个程序,用于计算文本文件中的字符,单词和行,并报告计数.将单词定义为任何字母和/或数字序列,不带标点符号或空格.标点符号和空格不算作单词.

现在我写下了代码:

%{
#include <stdio.h>
#include <stdlib.h>
int cno = 0, wno = 0, lno = 0; /*counts of characters, words and lines */
%}
character [a-z]
digit [0-9]
word ({character}|{digit})+[^({character}|{digit})]
line \n
%%
{line} { lno++; REJECT; }
{word} { wno++; REJECT; }
{character} { cno++; }
%%
void main()
{ yylex();
  fprintf(stderr, "Number of characters: %d; Number of words: %d; Number of lines: %d\n", cno, wno, lno);
  return;
}
Run Code Online (Sandbox Code Playgroud)

我用文本文件测试了它:

this is line #1
line #2 is …
Run Code Online (Sandbox Code Playgroud)

compiler-construction yacc lex compilation

2
推荐指数
1
解决办法
3万
查看次数

Bison:错误消息中包含的行号

好的,所以我想我的问题是不言而喻的。

我目前正在Bison中构建一个解析器,并且我想使错误报告更好一些。

目前,我已设置%define parse.error verbose(实际上会发出类似的消息syntax error, unexpected ***********************, expecting ********************

我只想在错误消息中添加一些更多信息,例如行号(在输入/文件/等位置)

我目前yyerror(没什么...不寻常...大声笑):

void yyerror(const char *str)
{
    fprintf(stderr,"\x1B[35mInterpreter : \x1B[37m%s\n",str);
}
Run Code Online (Sandbox Code Playgroud)

聚苯乙烯

  • 我浏览了最新的Bison文档,但是我似乎很迷路...
  • 我也研究了该%locations指令,该指令很可能与我需要的指令非常接近-但是,我仍然没有找到完整的工作示例,并且不确定如何使用该指令。

c++ yacc lex bison flex-lexer

2
推荐指数
1
解决办法
3683
查看次数

如何用赋值(=)和相等(==)操作数制作语法?

作为我正在参加的“编译器理论”课程的一项作业,我必须用lex / yacc编码计算器。一些要求是:

  • 用户必须能够将数字或布尔值分配给变量
  • 计算器必须能够比较布尔语句

如果我尝试输入以下内容:

a=5;
a; // Output: 5
a==5; // Syntax error
Run Code Online (Sandbox Code Playgroud)

但是,如果我输入以下内容,它将起作用:

5==a; // Output: 1
Run Code Online (Sandbox Code Playgroud)

我认为问题在于yacc正在读取a==5的是表格的新赋值,<a> <=> <=5>而不是<a> <==> <5>。我仍然不知道如何解决该问题。我尝试使用%prec注释,但这不能解决问题。

这是代码:calc.l

%{
#include "y.tab.h"
void yyerror(char* s);
%}

%%
"exit"      { return exit_command; }
[0-9]+      { yylval.num = atoi(yytext); return number; }
[a-zA-Z]    { yylval.id = yytext[0]; return identifier; }
[ \t\n]     ;
[-+*/()^%;] { return yytext[0]; }
[<>=!&|]    { return yytext[0]; }
.       { ECHO; yyerror("Unexpected character"); } …
Run Code Online (Sandbox Code Playgroud)

c yacc lex

2
推荐指数
1
解决办法
65
查看次数