メタプログラミング言語用の単純なパーサーを作成しようとしています。すべて正常に動作しますが、「;」を使用したい 改行やセミコロン全体の省略ではなく、ステートメントの区切り記号として使用します。
したがって、これは予想される動作です。
// 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