在我的bison/flex程序中,在调用yyparse()之后,会打印一个前导选项卡,但我不知道为什么.你能看出什么是错的吗?
这会调用bison代码,并在yyparse()返回后立即打印一个选项卡.
void parseArguments(int argc, char** argv)
130 {
131 int i;
132
133 int sum = 0;
134 // calculate the length of buffer we need
135 for(i = 1; i < argc; i++)
136 {
137 sum += strlen(argv[i]) + 1;
138 }
139
140 if(sum <= 0)
141 return;
142
143 // make us a buffer and zero it out
144 char tempBuffer[sum];
145 memset(tempBuffer, 0, sum);
146
147 // pointer to walk through our buffer
148 …Run Code Online (Sandbox Code Playgroud) 我回来了,现在正在编写我自己的语言和我的操作系统,但是由于我现在开始开发自己的开发语言,因此在使用Bison时我遇到了一些错误,我不知道如何解决它们.这是我的*.y文件代码:
input:
| input line
;
line: '\n'
| exp '\n' { printf ("\t%.10g\n", $1); }
;
exp: NUM { $$ = $1; }
| exp exp '+' { $$ = $1 + $2; }
| exp exp '-' { $$ = $1 - $2; }
| exp exp '*' { $$ = $1 * $2; }
| exp exp '/' { $$ = $1 / $2; }
/* Exponentiation */
| exp exp '^' { $$ = pow ($1, …Run Code Online (Sandbox Code Playgroud) 在较大的程序中,我给出了以下(flex/bison)
在flex中:
pn [\+|\-]
dig [0-9]+
exp [e|E]{dig}+
Run Code Online (Sandbox Code Playgroud)
.
.
.
"+" {printf("+ detected\n");
return PLUS_SIGN;}
{pn}?{dig}+ { printf("digit detected - %s\n",yytext);
sscanf(yytext, "%d", (int*)&yylval);
return TYPE_INT;}
Run Code Online (Sandbox Code Playgroud)
在野牛:
expr:
expr PLUS_SIGN expr
{
$$ = $1 + $3;
printf(" $$=%f\n",$$);
}
| TYPE_INT
{
$$ = (int)$1;
printf(" $$=%f\n",$$);
}
;
Run Code Online (Sandbox Code Playgroud)
问题是:
当我给2 + 2时,它识别2和+2而不是2,+,2
我怎么能让它做这个添加?
在我的 yacc 文件中,我有一个开始符号“Program”,如下所示:
Program: Declaration Statements E_O_F {/*Semantic Action*/};
Run Code Online (Sandbox Code Playgroud)
E_O_F 是由 flex-lexer 返回的标记,如下所示:
<<EOF>> return E_O_F;
Run Code Online (Sandbox Code Playgroud)
但是当我编译我的文件时,总是在最后一行+第 1 行报告语法错误。Lex 文件:文件 Yacc 文件:文件
输入:测试.txt
a=(b);
b=c+d/e;
a=3/5-2*4;
a=a-b;
if(a>b)
{
a=a+1;
}
Run Code Online (Sandbox Code Playgroud)
我想我不会退货
<<EOF>>
Run Code Online (Sandbox Code Playgroud)
正确标记。请帮忙。
我正在尝试学习如何使用 Jison(使用 Bison 语法的 Javascript 解析器生成器)。
我有一些看起来像这样的代码:
a: "{{index()}}"
b: "{{blah(2, 'aba')}}"
Run Code Online (Sandbox Code Playgroud)
我正在尝试创建一个解析器,index()如果通过 stringa和blah(2, 'aba')如果通过 string将返回b。(本质上,我需要解析包含方法调用的字符串)。
我一直在尝试适应 Jison 提供的示例,但由于我对解析的工作原理缺乏了解而受到阻碍!
这是我的语法文件:
/* lexical grammar */
%lex
%%
\s+ /* skip whitespace */
[a-zA-Z0-9]+ return 'STR'
"{{" return '{{'
"}}" return '}}'
<<EOF>> return 'EOF'
. return 'INVALID'
/lex
/* operator associations and precedence */
%token '{{' '}}'
%start expressions
%% /* language grammar */
expressions
: e EOF
{ typeof console !== 'undefined' …Run Code Online (Sandbox Code Playgroud) 我用弯曲和野牛为了使一个词法分析器和解析器为EBNF语法.这项工作完成了!我的意思是,当我把一个文件放入我写的程序时,我可以看到程序是否有错误.如果没有,我可以根据我使用的语法在屏幕上看到整个程序.我没有问题.
现在,我想使用循环处理和循环展开.我应该改变哪一部分?词法分析器?解析器?还是解析器之后的主要?如何?
我正在使用野牛来构建用于教育目的的解析器。这是我非常简单的语法:
program: KW_VAR ident {printf("var %s\n", $2);} ;
ident:
| IDENTIFIER OP_PLUS IDENTIFIER {sprintf($$, "%s + %s\n", $1, $3);}
;
Run Code Online (Sandbox Code Playgroud)
其中KW_VAR代表单词“ var”,OP_PLUS代表运算符“ +”。
var hello + hi是此语法可接受的短语。因此,当我使用上面的代码时,一切正常,printf给出:var hello + hi按预期。但是,当我尝试更改sprintf中$ 1,$ 3的顺序时,如下所示,printf给出:var hi + hi +。我期望的是var hi + hello。
program: KW_VAR ident {printf("var %s\n", $2);} ;
ident:
| IDENTIFIER OP_PLUS IDENTIFIER {sprintf($$, "%s + %s\n", $3, $1);}
;
Run Code Online (Sandbox Code Playgroud)
为什么会这样呢?我的代码有问题吗?
我真的更喜欢一个有效的例子来解释.无论我到目前为止在Bison的文档网站上所阅读的内容都与Flex所说的相矛盾.有人说要宣布yylex为
int yylex (yyscan_t yyscanner);
Run Code Online (Sandbox Code Playgroud)
另一个人希望它是:
int yylex(YYSTYPE *lvalp, YYLTYPE *llocp);
Run Code Online (Sandbox Code Playgroud)
我真正需要的是位置信息.我现在还不确定是否需要YYSTYPE(我现在没有使用这些信息,但将来我可能会这样做).
与上述无关,作为奖励,我很有兴趣知道为什么这个基础设施如此糟糕.这似乎是一件非常直截了当的事情,但它却非常糟糕.它从不适用于默认值.即使编写一个最简单的教科书计算器示例,也需要多天修复配置错误...为什么?
我正在尝试为编译器生成中间代码。我在macOS上使用flex-bison。当我尝试输入时,出现语法错误,并且我不知道该语法错误来自何处。
这是我的词法:
%{
#include<stdbool.h>
#include <stdlib.h>
#include <string.h>
//#include "LinkedList.h"
#include "parser.tab.h"
char* tempString;
%}
%option yylineno
whole 0|[1-9][0-9]*
real {whole}\.(([0-9])|([0-9][0-9]*[1-9]))
divisionop [/]
noSymbol [^ \t\n\/\+\-\*\:\;\,\(\)\.]
error {noSymbol}+
%%
[ \t\n\r]+ ;
\#[-+]?{whole}/[\ :\,\;\+\-\/\*\)\n\r]|".GT."|".GE."|".EQ."|".NE."|".LT."|".LE."|":=" {
char* string = (char*) malloc(strlen(yytext));
strcpy(string, yytext + 1);
string[strlen(string)] = 0;
//printf("Found integer : %d\n", atoi(string));
//push(string,INTEGER,yylineno);
return INTEGER;}
\#[-+]?{real}/[\ :\,\;\+\-\/\*\)\n\r]|".GT."|".GE."|".EQ."|".NE."|".LT."|".LE."|":=" {
char* string = (char*) malloc(strlen(yytext));
strcpy(string, yytext + 1);
string[strlen(string)] = 0;
//printf("Found real:%s\n",string);
//push(string,REAL,0);
return REALNUM;
}
[a-zA-Z][0-9][0-9a-zA-Z]* {
//printf("Found identifier:%s\n",yytext); …Run Code Online (Sandbox Code Playgroud) 因此,我正在为C创建编译器,而我目前正在创建文字,变量和函数表。
这条规则使我减少/减少冲突:
lval: ID { check_var(); }
| ID { check_var(); } LBRACK NUM RBRACK
| ID { check_var(); } LBRACK ID { check_var(); } RBRACK;
Run Code Online (Sandbox Code Playgroud)
错误如下:
parser.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
parser.y:104.6-21: warning: rule useless in parser due to conflicts [-Wother]
| ID { check_var(); } LBRACK ID { check_var(); } RBRACK;
^^^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
我有优先规则,可以避免减少令牌上的错误,但是现在它指向的是非令牌,所以不确定我应该怎么做?
如果有任何帮助,这些是我的优先规则:
%token INPUT OUTPUT WRITE
%token RETURN VOID IF ELSE WHILE ASSIGN SEMI COMMA
%token LPAREN RPAREN LBRACE RBRACE LBRACK RBRACK
%token NUM ID …Run Code Online (Sandbox Code Playgroud) 我一直在尝试打印一个字符串文字,但似乎我做错了,因为我收到了编译警告.这可能是由于错误的格式化或我对c_str()功能的误解,我认为应该返回一个string.
parser.y: In function ‘void setVal(int)’:
parser.y:617:41: warning: format not a string literal and no format arguments [-Wformat-security]
Run Code Online (Sandbox Code Playgroud)
617行:
sprintf(temp, constStack.top().c_str());
Run Code Online (Sandbox Code Playgroud)
有这些声明
#include <stack>
const int LENGTH = 15;
char *temp = new char[LENGTH];
stack<string> constStack;
Run Code Online (Sandbox Code Playgroud)
如何为字符串提供正确的格式?
bison ×11
flex-lexer ×5
c ×4
c++ ×2
parsing ×2
yacc ×2
calculator ×1
char ×1
ebnf ×1
grammar ×1
javascript ×1
jison ×1
lex ×1
loops ×1
stack ×1