2

メタプログラミング言語用の単純なパーサーを作成しようとしています。すべて正常に動作しますが、「;」を使用したい 改行やセミコロン全体の省略ではなく、ステートメントの区切り記号として使用します。

したがって、これは予想される動作です。

// good code
v1 = v2;
v3 = 23;

エラーなしで解析する必要があります

しかし:

// bad code
v1 = v2
v3 = 23;

失敗すべき

それでも、セパレーターから「空の」ルールを削除すると、両方のコードが次のように失敗します。

ID to ID
Error detected in parsing: syntax error, unexpected ID, expecting SEMICOLON
;

「空の」ルールをアクティブのままにすると、両方のコードが受け入れられますが、これは望ましくありません。

ID to ID   // should raise error
ID to NUM;

ほとんどのチュートリアルでは区切り文字がまったくカバーされていないため、ここでヘルプを歓迎します。

これが私のパーサー/レクサーの簡略版です。

parser.l:

%{
#include "parser.tab.h"
#include<stdio.h>
%}

num      [0-9]
alpha    [a-zA-Z_]
alphanum [a-zA-Z_0-9]
comment "//"[^\n]*"\n"
string  \"[^\"]*\"
whitespace [ \t\n]

%x ML_COMMENT


%%
<INITIAL>"/*"               {BEGIN(ML_COMMENT); printf("/*");}
<ML_COMMENT>"*/"            {BEGIN(INITIAL); printf("*/");}  
<ML_COMMENT>[.]+            { }
<ML_COMMENT>[\n]+           { printf("\n"); }
{comment}+                  {printf("%s",yytext);}

{alpha}{alphanum}+          { yylval.str= strdup(yytext); return ID;}
{num}+                      { yylval.str= strdup(yytext); return NUM;}
{string}                    { yylval.str= strdup(yytext); return STRING;}

';'                         {return SEMICOLON;}
"="                         {return ASSIGNMENT;}
" "+                        { }
<<EOF>>                     {exit(0); /* this is suboptimal */}
%%

パーサー.y:

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

%error-verbose

%union{
        char *str;
}

%token  <str> ID
%token  <str> NUM
%token  <str> STRING
%left SEMICOLON
%left ASSIGNMENT

%start input

%%
input:  /* empty */
        | expression separator input
;

expression: assign 
            | error {}
;

separator:  SEMICOLON
            | empty
;

empty:      
;

assign:   ID ASSIGNMENT ID      { printf("ID to ID"); }
        | ID ASSIGNMENT STRING  { printf("ID to STRING"); }
        | ID ASSIGNMENT NUM     { printf("ID to NUM"); }
;

%%

yyerror(char* str)
{
        printf("Error detected in parsing: %s\n", str);
}

main()
{
        yyparse();
}

次のようにコンパイルされます。

$>flex -t parser.l > parser.lex.yy.c
$>bison -v -d parser.y
$>cc parser.tab.c parser.lex.yy.c -lfl -o parser
4

1 に答える 1

3

気にしないでください...問題のある行は次のとおりです。

';'                         {return SEMICOLON;}

に変更する必要がありました

";"                         {return SEMICOLON;}

これで動作は正しくなりました。:-)

于 2012-10-12T17:36:29.100 に答える