标签: yacc

.NET有一个很好的yacc/bison类型LALR解析器生成器吗?

.NET有一个很好的yacc/bison类型LALR解析器生成器吗?

.net yacc lalr

7
推荐指数
2
解决办法
2563
查看次数

如何在lex中使用yy_scan_string

我想在yacc的main函数中解析我给解析器的字符串.我知道这可以通过使用来完成,yy_scan_string但我不知道如何使用它.我搜索了网页和手册页,但我仍然不清楚.请帮我.

c yacc lex

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

如何设置flex/bison规则来解析逗号分隔的参数列表

我希望能够使用flex/bison解析规则解析非空的,一个或多个元素,逗号分隔(以及可选的带括号的)列表.

一些例如可解析的列表:

  • 1
  • 1,2
  • (1,2)
  • (3)
  • 3,4,5
  • (3,4,5,6-)

等等

我使用以下规则来解析列表(最终结果是解析元素'顶级列表'),但它们在解析时似乎没有给出所需的结果(在提供有效列表时我得到语法错误).关于我如何设置它的任何建议?

cList :   ELEMENT
           {
              ...
           }
        | cList COMMA ELEMENT
           {
              ...
           }
        ;

topLevelList :  LPAREN cList RPAREN
                 {
                     ...                 
                 }
              | cList
                 {
                     ...
                 }
          ;
Run Code Online (Sandbox Code Playgroud)

parsing yacc lex bison flex-lexer

7
推荐指数
1
解决办法
5340
查看次数

从解析器控制Python PLY词法分析器状态

我正在研究一个简单的SQL选择,如查询解析器,我需要能够捕获可以在某些地方字面上出现的子查询.我发现lexer状态是最好的解决方案,并且能够使用花括号来标记开始和结束.但是,子查询将用括号分隔,而不是用卷曲分隔,括号也可以在其他地方出现,所以我不能成为每个开放状态的状态.解析器随时可以使用此信息,因此我希望在解析器规则中的适当位置调用begin和end.然而这并不起作用,因为词法分析器似乎一次性标记了流,因此令牌在INITIAL状态下生成.这个问题有解决方法吗?以下是我尝试做的概述:

def p_value_subquery(p):
    """
     value : start_sub end_sub
    """
    p[0] = "( " + p[1] + " )"

def p_start_sub(p):
    """
    start_sub : OPAR
    """
    start_subquery(p.lexer)
    p[0] = p[1]

def p_end_sub(p):
    """
    end_sub : CPAR
    """
    subquery = end_subquery(p.lexer)
    p[0] = subquery
Run Code Online (Sandbox Code Playgroud)

start_subquery()和end_subquery()定义如下:

def start_subquery(lexer):
    lexer.code_start = lexer.lexpos        # Record the starting position
    lexer.level = 1
    lexer.begin('subquery') 

def end_subquery(lexer):
    value = lexer.lexdata[lexer.code_start:lexer.lexpos-1]
    lexer.lineno += value.count('\n')
    lexer.begin('INITIAL')
    return value
Run Code Online (Sandbox Code Playgroud)

词法分析器令牌只是用于检测近距离:

@lex.TOKEN(r"\(")
def t_subquery_SUBQST(t):
    lexer.level += 1

@lex.TOKEN(r"\)")
def t_subquery_SUBQEN(t):
    lexer.level -= …
Run Code Online (Sandbox Code Playgroud)

python yacc ply lexer

7
推荐指数
2
解决办法
2625
查看次数

在yacc中%左和右

{%
#include<stdio.h>
#include<stdlib.h>
%}

%token ID NUM IF THEN LE GE EQ NE OR AND ELSE

%right '='
%left AND OR
%left '<' '>' LE GE EQ NE
%left '+''-'
%left '*''/'
%right UMINUS
%left '!'

%%
Run Code Online (Sandbox Code Playgroud)

提到上面是yacc程序的一部分,用于简单的IF ELSE程序....我只是一个初学者而且不明白我们的意思%right%left术语...... plz在这个场合帮助我......

compiler-construction syntax gcc yacc if-statement

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

规则空缺右侧的符号

当使用带有空右侧的规则编写("理论")语法时,总是使用诸如ε(或1)之类的符号来使这个空白显式:

A ? ? | a A
Run Code Online (Sandbox Code Playgroud)

Yacc和其他人的这种语法看起来就像

a: | 'a' a
Run Code Online (Sandbox Code Playgroud)

或"更糟"

a:       { $$ = new_list(); }
 | a 'a' { $$ = $1; $$->append($1); }
 ;
Run Code Online (Sandbox Code Playgroud)

事实上,在"真实世界语法"(Yacc,Bison等)规则的这个空的右侧部分没有明确标记为空的麻烦我:很容易错过rhs空的事实,或者更糟糕的是:忘记插入|并实际使用中规则操作:

a:       { $$ = new_list(); }
   a 'a' { $$ = $1; $$->append($1); }
 ;
Run Code Online (Sandbox Code Playgroud)

1)我不知道有任何工具可以提供显式空rhs的方法.有吗?

Bison的未来版本可能支持专用符号,在非空rhs中使用时会出现错误,而在留下隐式空rhs时会出现警告.

2)人们认为这有用吗?

3)你建议的符号是什么?

目前,候选人是$empty:

a: $empty { $$ = new_list(); }
 | a 'a'  { $$ = $1; $$->append($1); }
 ;
Run Code Online (Sandbox Code Playgroud)

编辑

选择的语法是%empty:

a: %empty { $$ = …
Run Code Online (Sandbox Code Playgroud)

yacc bison parser-generator

7
推荐指数
2
解决办法
9038
查看次数

获取:警告,规则无法匹配

我正在构建一个词法和语法分析器.当我尝试将flex与我的.l文件一起使用时,我收到以下警告.

littleDuck.l:26: warning, rule cannot be matched
Run Code Online (Sandbox Code Playgroud)

规则26是以{cteI}开头的规则,我的规则部分如下:

[ \t\n]     ;
{RW}        {return RESERVED;}
{id}        {return ID;}
{ops}       {return OPERATOR;}
{seps}      {return SEPARATOR;}
{cteI}      {yylval.ival = atoi(yytext); return INT;}
{cteF}      {yylval.fval = atof(yytext); return FLOAT;}
{ctestring} {yylval.sval = strdup(yytext); return STRING;}
.       ;
Run Code Online (Sandbox Code Playgroud)

另外,我的定义部分是这样的:

RW      program|var|int|float|print|else|if
id      ([a-z]|[A-Z)([a-z]|[A-Z]|[0-9])*
ops     "="|"<"|">"|"<>"|"+"|"-"|"/"|"*"
seps    ":"|","|";"|"{"|"}"|"("|")"
cteI    [0-9]+
cteF    {cteI}(\.{cteI}((e|E)("+"|"-")?{cteI})?)?
ctestring   (\".*\")
Run Code Online (Sandbox Code Playgroud)

为什么会出现此警告,如何修改我的文件以使其不显示?

yacc lex bison flex-lexer

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

我该如何处理Flex词法分析器中的词法错误?

我目前正在尝试使用Flex + Bison编写一个小编译器,但我在错误处理方面有点迷失,特别是如何使所有东西都融合在一起.为了激发讨论,请考虑我用于字符串文字的以下词法分析器片段:

["]          { BEGIN(STRING_LITERAL); init_string_buffer(); }
<STRING_LITERAL>{
    \\\\    { add_char_to_buffer('\\'); }
    \\\"    { add_char_to_buffer('\"'); }
    \\.     { /*Invalid escape. How do I treat this error?*/ }
    ["]     { BEGIN(INITIAL); yylval = get_string_buffer(); return TK_STRING; }
}
Run Code Online (Sandbox Code Playgroud)

如何处理无效转义的情况?现在我只是打印一条错误消息并打电话exit但我更愿意继续前进并在可能的情况下检测每个文件多个错误.

我的问题:

  • 我用什么功能打印出错误信息?以后野牛预计会出现同样的错误吗?如果我有词法分析器和解析器的单独文件,我在哪里放置yyerror的定义?
  • 我应该从我的行动中返回什么令牌代码?0为"文件结束"?一些特殊的TK_INVALID_STRING令牌?
  • 如何确保解析器可以在词法错误(无效的文字,流浪标点字符等)后继续解析?

yacc lex bison lexer flex-lexer

7
推荐指数
1
解决办法
7243
查看次数

从lex和yacc语法生成编译器

我正在尝试生成一个编译器,所以我可以在之后传递一个.c文件.

我从http://www.quut.com/c/ANSI-C-grammar-y.html下载了YACC和LEX语法,并将它们命名为clexyacc.l和clexyacc.y

在终端上生成它时我做了:

yacc -d clexyacc.y
lex clexyacc.l
Run Code Online (Sandbox Code Playgroud)

一切都很好.当我继续到最后一部分时,我得到了一些错误.

最后一部分是:cc lex.yy.c y.tab.c -oclexyacc.exe

但我得到这些错误:

y.tab.c:2261:16: warning: implicit declaration of function 'yylex' is invalid in
      C99 [-Wimplicit-function-declaration]
      yychar = YYLEX;
               ^
y.tab.c:1617:16: note: expanded from macro 'YYLEX'
# define YYLEX yylex ()
               ^
y.tab.c:2379:7: warning: implicit declaration of function 'yyerror' is invalid
      in C99 [-Wimplicit-function-declaration]
      yyerror (YY_("syntax error"));
      ^
clexyacc.y:530:6: error: conflicting types for 'yyerror'
void yyerror(const char *s)
     ^
y.tab.c:2379:7: note: previous implicit declaration is here
      yyerror (YY_("syntax …
Run Code Online (Sandbox Code Playgroud)

c yacc lex

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

从flex/bison中释放strdup()中分配的字符串

我有使用复制字符串lexeme的flex代码strdup().

%{   
#include "json.tab.h"
#define YY_DECL extern "C" int yylex()

%}
%option noyywrap

%%

[ \t\n]+ ; 
\"[a-zA-Z]+\" {yylval.sval = strdup(yytext); return STRING; }
[0-9]+ {yylval.ival = atoi(yytext); return NUMBER; }
. {return yytext[0];} ; 

%%
Run Code Online (Sandbox Code Playgroud)

strdup()分配内存并将输入字符串复制到其中并返回(strdup() - 它在C中做了什么?),所以我想当我不再需要它时我需要释放它.

从这篇文章:什么是在BISON中调用%析构函数?,我%destructor { free($$); printf("free");} STRING在yacc文件中添加了.

但是,free()即使yylval.sval从返回的新字符串赋值,我也看不到调用strdup().

可能有什么问题?如何释放flex/bison中分配的字符串?

添加

我想如下使用静态分配的sval:

%union {
    int ival;
    char sval[100]; // char* sval;
}
Run Code Online (Sandbox Code Playgroud)

flex代码现在变为(如果yytext小于100字节,则没有检查代码):

\"[a-zA-Z]+\" {
    //yylval.sval = strdup(yytext);
    memset(yylval.sval, …
Run Code Online (Sandbox Code Playgroud)

c yacc bison strdup flex-lexer

6
推荐指数
1
解决办法
2458
查看次数