[英]Unintentional concatenation in Bison/Yacc grammar
我正在嘗試使用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組成。 現在,您將在解析器中注意到args是使用前導冒號輸出的,目的是,當與語句規則的第一個模式結合使用時,與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); }
;
具有總輸入字符串的語義值,包括換行符? 我的語法如何重新編寫,以便我打算進行交互?
如果您希望令牌字符串保持有效,則必須在讀取它們時保留它們。 我將statement
規則修改為:
statement: ID { printf("<%s> ", $<strV>1); } args { printf("%s", $<strV>1); }
| INTEGER { printf("%d", $<intV>1); }
;
然后,根據您的輸入,我得到輸出:
> aaa aa a
<aaa> :aa :a aaa aa a
>
請注意,在讀取初始ID時,令牌正是您所期望的。 但是,因為您沒有保留令牌,所以在解析args
之后返回打印時,字符串已被修改。
我認為args和語句產生之間存在關聯性沖突。 這可以通過bison -v
parser.output文件的(部分)輸出得到證實:
Nonterminals, with rules where they appear
$accept (6)
on left: 0
program (7)
on left: 1 2 3, on right: 0 1 2
statement (8)
on left: 4 5, on right: 1
args (9)
on left: 6 7, on right: 4 7
EOF (10)
on left: 8, on right: 1 2
實際上,我很難弄清楚你的語法試圖接受什么。 作為旁注,我可能會將您的EOF作品作為EOL令牌移動到詞法分析器中; 這將使解析錯誤的重新同步更容易。
更好地解釋你的意圖會有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.