私は自分自身のミニ言語用のパーサーを構築しようとしています。それはYACC自身によってC++に翻訳されています。LEX + YACCはルールの次の行にトークンを取っています
問題は、YACCは入力の第2行から最初のトークンだけでなく第1行も読み取っていて、それを対応するルールと照合していますが、入力の最初の行でトークンのみを読み取る必要があります。対応するルールでそれを一致
私の入力ファイルは次のとおりです。
print "hello"
a = 10
print a
レックスファイル:
%{
#include <stdio.h>
#include "y.tab.h"
%}
alpha [a-zA-Z]
digit [0-9]
%%
[ \t] ;
[ \n] { yylineno = yylineno + 1;}
print {yylval = strdup(yytext); return PRINT;}
{alpha}({alpha}|{digit})* {yylval = strdup(yytext); return ID;}
{digit}+ {yylval = strdup(yytext); return INTEGER;}
\".*\" {yylval = strdup(yytext); return STRING;}
"=" return ASSIGN;
%%
YACCファイルがある:
%{
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
extern int yylineno;
extern FILE *yyin;
extern FILE *yyout;
extern char *yytext;
%}
%token PRINT INPUT INTO ASSIGN INTEGER DECIMAL BOOLVAL CHARACTER
%nonassoc STRING
%nonassoc ID
%%
entry: entry action {fprintf(yyout, "\t%s", $2); }
| action {fprintf(yyout, "\t%s", $1); }
;
action : print {$$ = $1;}
| assign {$$ = $1;}
;
print : PRINT ID {
printf("rule: PRINT ID");
char* id = strdup($2);
strcpy($$, "");
strcat($$,"cout<<");
strcat($$,id);
strcat($$,"<<endl;\n");
}
| PRINT STRING {
printf("rule: PRINT STRING\n");
char* str = strdup($2);
strcpy($$, "");
strcat($$,"cout<<");
strcat($$,str);
strcat($$,"<<endl;\n");
}
| PRINT STRING ID {
printf("rule: PRINT STRING ID\n");
char* str = strdup($2);
char* id = strdup($3);
strcpy($$, "");
strcat($$,"cout<<");
strcat($$,str);
strcat($$,"<<");
strcat($$,id);
strcat($$,"<<endl;\n");
}
;
assign: ID ASSIGN INTEGER {
char* id = strdup($1);
char* val = strdup($3);
strcpy($$,"");
strcat($$,"int ");
strcat($$,id);
strcat($$," = ");
strcat($$,val);
strcat($$,";\n");
}
;
%%
int main(int argc, char *argv[])
{
yyin = fopen(argv[1], "r");
yyout = fopen("out.txt","w");
if(!yyparse())
printf("\nParsing complete\n");
else
printf("\nParsing failed\n");
//fclose(yyin);
fclose(yyout);
return 0;
}
yyerror(char *s) {
printf("\n \nLine: %d, Message: %s, Cause: %s\n", yylineno, s, yytext);
}
yywrap()
{
return 1;
}
期待出力は次のとおりです。
cout<<"hello"<<endl;
int a = 10;
cout<<a<<endl;
しかし、構文解析が失敗した、などの部分的な出力を持つ:
cout<<"hello"<<a<<endl;
、エラーメッセージ:に使用
Line: 2, Message: syntax error, Cause: =
ルール減らすことが想定されている(同じord ER):
PRINT STRING ID
と解析はPRINT STRING
後、
ID
PRINT STRING
ID ASSIGN INTEGER
PRINT ID
しかし、最初のルールを軽減するために使用されているです使用されるのはPRINT STRING ID
です。
私は
%nonassoc STRING
%nonassoc ID
が問題ということです(私は以下のコードが何を意味するのかを推測)ID
上STRING
に低い優先度を与えてくれましたか?
私は何が起こっているのか理解できません。何か不足していますか?
あなたはトークンを返すこと、つまり\ nごとにNEWLINEと言って、PRINT STRING NEWLINEやID ASSIGN INTEGER NEWLINEのようなルールを使用しますか? –
@Abhilashk - はい、正確 – antlersoft