私は lex と yacc を試していて、奇妙な問題に遭遇しましたが、問題を詳しく説明する前に私のコードをお見せするのが最善だと思います。これは私のレクサーです:
%{
#include <stdlib.h>
#include <string.h>
#include "y.tab.h"
void yyerror(char *);
%}
%%
[a-zA-Z]+ {
yylval.strV = yytext;
return ID;
}
[0-9]+ {
yylval.intV = atoi(yytext);
return INTEGER;
}
[\n] { return *yytext; }
[ \t] ;
. yyerror("invalid character");
%%
int yywrap(void) {
return 1;
}
これは私のパーサーです:
%{
#include <stdio.h>
int yydebug=1;
void prompt();
void yyerror(char *);
int yylex(void);
%}
%union {
int intV;
char *strV;
}
%token INTEGER ID
%%
program: program statement EOF { prompt(); }
| program EOF { prompt(); }
| { prompt(); }
;
args: /* empty */
| args ID { printf(":%s ", $<strV>2); }
;
statement: ID args { printf("%s", $<strV>1); }
| INTEGER { printf("%d", $<intV>1); }
;
EOF: '\n'
%%
void yyerror(char *s) {
fprintf(stderr, "%s\n", s);
}
void prompt() {
printf("> ");
}
int main(void) {
yyparse();
return 0;
}
文字列と整数、および基本的な REPL だけで構成される、非常に単純な言語。ここで、パーサーで、引数が先頭のコロンで出力されることに注意してください。意図は、ステートメントの規則の最初のパターンと組み合わせると、REPL との相互作用が次のようになります。
> aaa aa a
:aa :a aaa>
ただし、相互作用は次のとおりです。
> aaa aa a
:aa :a aaa aa aa
>
次のルールでトークン ID が
statement: ID args { printf("%s", $<strV>1); }
| INTEGER { printf("%d", $<intV>1); }
;
改行を含めて、入力文字列全体の意味値を持っていますか? 意図した対話ができるように、どのように文法を作り直すことができますか?