YACC:带有另一个令牌一次或多次的令牌(重复)

时间:2014-11-26 23:12:15

标签: yacc lex optional repeat

需要一些帮助,因为我的谷歌在这项任务中似乎很弱。

从Lex / Yacc开始,到目前为止一直很好但是我对这个概念验证有一个奇怪的要求。我需要重复和可选的令牌。

我有一个包含以下内容的文本文件:

instance 0 {
    application 0 {
        id 0 {
            server 10.143.23.240
            server backup 10.132.34.240
        }
        id 24 {
            server 10.143.23.240
        }
    }
}

如上所述,Lex很好:

%{
#include <stdio.h>
#include <string.h>
#include "y.tab.h"

%}

%%

\{                                                              return OBRACE;
\}                                                              return CBRACE;

instance                                                        return INSTANCE;
id[0-9]+                                                        return ID;
        application                                             return APPLICATION;
                id                                              return ID;
                        server                                  return SERVER;
                        backup                                  return backup;
                        [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+          { yylval.string = strdup(yytext);
                                                                        return SERVER_IPADDRESS; }
[0-9]+                                                          { yylval.string = strdup(yytext);
                                                                        return NUMBER; }
[ \t\n]+                                                        /* ignore whitespace */;
.                                                               printf("%s\n", "Incorrect syntax");
%%

语法/ Yacc如下所示,并且已经简化以提供上下文,并且没有显示重复,因为我不知道如何解决它:

commands: /* empty */
        | commands command
        ;

command:
        server
        ;

server:
        SERVER SERVER_IPADDRESS
        {
                char server_ip_from_yyval[257] = { '\0' };

                if(NULL == $2){
                        printf("%s\n", "SERVER_IPADDRESS is NULL");
                }
                else{
                        strncpy(server_ip_from_yyval, $2, 256);
                        set_server_ip(server_ip_from_yyval);
                }
        }
        ;
%%
$ 
$ 

所以我的挑战是:

1.。)如何允许文本文件中的“id”或Lex文件中的ID可以选择出现一次或多次? 2.)允许文本文件中的“服务器备份”是可选的吗?

我看了一些参考文献(下面几个),但我很难找到正确的答案:

This switch statement is working with one Case how to make it multiple case Bison yacc - How to do a if condition Bison: how to fix reduce/reduce conflict

非常感谢任何帮助。 :)

感谢阅读。

1 个答案:

答案 0 :(得分:0)

这样的事情,取决于您的嵌套规则:

commands
    : instances
    ;

instances
    : instance /* or empty if there can be zero instances */
    | instances instance
    ;

instance
    : INSTANCE ids '{' applications '}'
    ;

applications
    : application /* or empty if there can be zero applications */
    | applications application
    ;

application
    : APPLICATION ids '{' servers '}'
    ;

servers
    : server /* or empty if there cabn be zero servers */
    | servers server
    ;

server
    : SERVER backup ids SERVER_IPADDRESS
    {
        // etc. as you have now
    }
    ;

ids
    : ID /* You probably don't want to allow zero IDs */
    | ids ID
    ;

backup
    : /* empty */
    | BACKUP
    ;

这应该给你一般的想法。

请注意,您不需要&#39; {&#39;并且&#39;}&#39;:只有这样的最终规则:

. return yytext[0];

涵盖所有特殊字符。使用这种技术,非法字符将返回到解析器,解析器将它们作为语法错误处理。

相关问题