- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试制作一个简单的解析器。这是为了家庭作业,也是为了自己的实验。我已经完成了词法分析器和解析器,现在正在尝试输出 AST。问题是,例如,当我添加两个整数时,结果树会打印出无法识别的符号。有效输入应为 +(1,1)
,有效输出应为 (+ 1 1)
。而不是这个,我得到 ( + �|k �|k )
。我尝试了很多东西,实际上没有任何显着的结果。 sprintf
函数返回一个空终止符,所以这可能不是问题所在。以下是解析器代码(.y 文件):
%{
#define YYDEBUG 1
%}
%start program
%token NUMBER
%token ID
%token PLUS MINUS TIMES
%token LP RP EQUALS COMMA
%token END
%token LET IN AND
%left PLUS MINUS
%left TIMES
%left LET IN AND
%left EQUALS
%%
program:{printf("Empty Input\n");} /* empty */
| program line /* do nothing */
line: expr END { printtree($1); printf("\n");}
;
expr : /*Empty*/
| LET deflist IN expr {}
| ID { printf("Found ID\n"); $$ = make_id_leaf($1);}
| NUMBER { printf("Found NUMBER\n"); $$ = make_number_leaf($1);}
| PLUS LP expr COMMA expr RP {$$ = make_plus_tree($3,$5); printf("Found expr PLUS expr.\n"); }
| TIMES LP expr COMMA expr RP {$$ = make_times_tree($3,$5); printf("Found expr TIMES expr. Result:%d\n", $$);}
| MINUS ID
| MINUS NUMBER { printf("found MINUS NUMBER\n"); }
;
deflist : definition
| definition AND deflist
;
definition : /*Empty*/
| ID EQUALS expr {printf("Found EQ\n");}
;
%%
/*int main (void) {return yyparse ( );}*/
int yyerror (char *s) {fprintf (stderr, "%s\n", s);}
词法分析器文件:
%{
#include "parser.h"
%}
DIGIT [0-9]
LETTER [a-zA-Z]
%%
LET {printf("Encountered LET\n"); return(LET);}
IN {printf("Encountered IN\n"); return(IN);}
AND {printf("Encountered AND\n"); return(AND);}
{DIGIT}+ {yylval = atoi(yytext); return NUMBER;}
{LETTER}* { if (strlen(yytext) <= 8){
yylval = strlen(yytext);
printf( "<ID, %s> ", yytext );
return(ID);
} else {
yytext[8] = '\0';
printf("WARNING! Long identifier. Truncating to 8 chars\n");
printf( "<ID, %s> ", yytext );
return(ID);
}
}
[ \t] ;
[\n] return(END);
"+" return(PLUS);
"-" return(MINUS);
"*" return(TIMES);
"=" return(EQUALS);
"(" return(LP);
")" return(RP);
"," return(COMMA);
<<EOF>> return(0);
%%
int yywrap (void) {return 1;}
包含yyparse() 函数的main.c:
#include <stdio.h>
#include <stdlib.h>
#include "tree.h"
#include "treedefs.h"
int main(int argc, char **argv){
yyparse();
return 0;
}
还有包含函数定义的 treedefs.h 文件(我只包含了结构定义、数字叶和加号树):
typedef struct tree{
char *token;
TREE *l;
TREE *r;
TREE *child;
}TREE;
/* Make number leaves */
TREE *make_number_leaf(int n){
TREE *leafNum = malloc(sizeof(TREE));
char *c, ch[8];
sprintf(ch, "%d", n); /* Effective way to convert int to string */
c = ch;
leafNum->token = c;
leafNum->l = NULL;
leafNum->r = NULL;
leafNum->child = NULL;
printf("NUM Leaf is: %s\n", leafNum->token);
return (leafNum);
}
/* Addition tree */
TREE *make_plus_tree(TREE *l, TREE *r){
TREE *plusTree = malloc(sizeof(TREE));
plusTree->token = "+";
plusTree->l = l;
plusTree->r = r;
plusTree->child = NULL;
return (plusTree);
}
void printtree(TREE *tree)
{
if (tree->l || tree->r){
printf("(");
}
printf(" %s ", tree->token);
if (tree->l){
printtree(tree->l);
}
if (tree->r){
printtree(tree->r);
}
if (tree->l || tree->r){
printf(")");
}
}
文件tree.h只是一些声明,没什么大不了的,绝对与问题无关。
为什么数字看起来像这样?我该如何解决?任何帮助将不胜感激。
最佳答案
这个问题其实和bison或者flex都没有关系。它在您的 make_number_leaf
实现中:
TREE *make_number_leaf(int n){
TREE *leafNum = malloc(sizeof(TREE));
char *c, ch[8];
// ^ local variable
sprintf(ch, "%d", n); /* Effective way to convert int to string */
c = ch;
leafNum->token = c;
// ^ dangling pointer
// Remainder omitted
}
如上面的注释所示,ch
是一个局部(堆栈分配)变量,其生命周期在函数返回时结束。将其地址分配给变量 c
不会改变它。所以leafNum->token
中存储的c
的值,一旦函数返回,就会变成悬空指针。
因此,当您稍后尝试打印出 token 时,您正在打印出随机存储器的内容。
您需要malloc
一个字符缓冲区,并记得在释放
TREE
时释放
它>。 (但是,在leafNum->token
是字符串字面量的情况下,你不能调用free
,所以你需要聪明一点。)
关于c - BISON AST 生产打印乱序值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31705988/
有没有更好的方法用 PHP 将数据输出到 html 页面? 如果我想在 php 中用一些 var 制作一个 div,我会写类似的东西 print (''.$var.''); 或 echo "''.$v
我可以使用 java awt print 来打印文档/文件而不是使用 javax print 吗?我发现在 java awt print 中有一个选项可以使用 AttributedString 将内容
目前我通过以下方式运行 R 脚本: R --slave argument1 argument2 ... 我想知道 R 中关于如何退出脚本并发出警告的最佳实践,q() 会这样做吗? if(!file.
谁能告诉我如何编写一个程序,用 gcc 编译时打印 c ,用 g++ 编译时打印 c++? 最佳答案 #ifdef __cplusplus printf("c++\n"); #else
我需要支持在 KitKat 设备上打印,但我的目标 SDK 是 13(无法更改)。 特别是我需要打印一个 webview。 这是用于打印 webview 的 API: http://developer
我正在尝试创建一个简单的函数,其中 python 将根据您的年份输入计算年龄。我已经尝试了几种方法,但我没有运气 atm。 附:对不起,我是新手。 ame = input(" Enter your n
JavaFX 2.0 是否支持打印?我有一个文本区域,我从中获取文本然后我想打印它,但似乎没有这个功能。 当然,这里我说的是打印到打印机。 :) 最佳答案 尚不支持。作为一种解决方法,您可以使用 Ja
我试图找出printOn的重点。我查看了一些实现它的类,看起来它只是帮助打印不同数据类型的单位。这是准确的吗? 如果是这样,有人能指出我如何为我自己的类(class)实现这一点的正确方向吗?我将在可能
我无法让 IE 打印我的 Canvas (使用 excanvas 生成)...我使用的是最新版本的 excanvas。 http://dl.dropbox.com/u/997831/canvas.ht
我搜索了很多但没有人回答我的问题,我读到在这样的信号处理程序中使用 cout 是不安全的: void ctrlZHandler(int sig_num) { //SIGTSTP-18
我有兴趣打印一系列查询。我有以下代码。 start = datetime.datetime(2012, 2, 2, 6, 35, 6, 764) end = datetime.datetime(201
public class javaClass { public static void main(String [] arg) { String row1 = "A____A"
我需要写入前一行的命令,例如不带\n 的 print()。 下面是一些示例代码: a=0 print("Random string value") if a==0: print_to_prev
我有一个使用 UIKit 和 Objective C 的旧 iOS 应用程序,我目前正在将其移植到 SwiftUI 和 Swift。一切都很顺利,我喜欢 Swift 和 SwiftUI。该应用程序已经
我创建了一个求和函数,它接受一个开始编号和一个结束编号,并返回这两点之间的总和答案 def print_sum_equations(start_number,end_number):
在 Perl 6 中,print 和有什么区别? , put和 say ? 我怎么看 print 5不同,但 put 5和 say 5看起来一样。 最佳答案 put $a就像 print $a.Str
我正在使用 here 中的 getOrgChart 库,我正在尝试打印整个图表,而不仅仅是可见部分。不幸的是,当使用标准库打印功能时,它只会打印出第一部分,而我不知道如何打印整个图表(该图表相当宽,大
我制作了一个非常适合 A4 页面的 View 。现在我想打印它。请注意,我没有使用drawRect或类似的东西,只是一个带有 subview 和文本标签的普通 View 。我的问题是,我对该 View
由于 Cocoa-Java 已弃用,我正在将 Cocoa-Java 代码迁移到 Cocoa + JNI。该代码打印存储在文件中的图像。新的 Cocoa 代码基本上是: NSImage *image =
这个问题已经有答案了: Printing a TDBGrid (4 个回答) 已关闭 6 年前。 如何在不安装或下载组件的情况下打印 DBGrid? 或者 如何将 DBGrid 的数据放入 RichE
我是一名优秀的程序员,十分优秀!