来自"野牛手册":
在一个简单的交互式命令解析器中,每个输入都是一行,允许yyparse在出错时返回1并让调用者在发生这种情况时忽略输入行的其余部分(然后再次调用yyparse)就足够了.
这几乎是我想要的,但我无法上班.基本上,我想在flex中检测和出错,如果检测到错误,让Bison丢弃整行.我现在所拥有的,是不是很正常,因为我的命令仍然执行:
kbsh: ls '/home
Error: Unterminated Single Quote
admin kbrandt tempuser
syntax error
kbsh:
Run Code Online (Sandbox Code Playgroud)
在我的Bison文件中:
commands:
/*Empty*/ { prompt(); } |
command { prompt(); }
;
command:
error {return 1; } |
chdir_command |
pwd_command |
exit_command |
WORD arg_list {
execute_command($1, $2);
//printf("%s, %s\n", $1, $2);
} |
WORD { execute_command($1, NULL); }
;
Run Code Online (Sandbox Code Playgroud)
在我的Flex中:
' {BEGIN inQuote; }
<inQuote>\n {printf("Error: Unterminated Single Quote\n"); BEGIN(0); return(ERROR);}
Run Code Online (Sandbox Code Playgroud) 我有这样的语法:
"匹配一个或多个rule1,其中rule1是一个或多个rule2,其中rule2是一个或多个rule3等,每个由换行符分隔".请看下面的例子.
start: rule1_list
;
rule1_list: rule1
| rule1_list NEWLINE rule1
;
rule1: rule2
| rule2 NEWLINE rule3_list
;
rule2: TERMINAL2
;
rule3_list: rule3
| rule3_list NEWLINE rule3
;
rule3 : TERMINAL3
;
Run Code Online (Sandbox Code Playgroud)
我这样做了转换/减少冲突,我怎样才能改变语法来停止?基本上它需要在新行之后进行分支,并查看下一个是TERMINAL2还是TERMINAL3.
用我的语言我可以写
a = 1
b = 2
if true { } else { }
if true { } **Here is the problem**
else {}
Run Code Online (Sandbox Code Playgroud)
我的语法不支持语句之间的换行符.else只能与if一起使用.当我在我的规则中添加optionalNL时
IfExpr:
IF rval optionalNL codeBlock optionalNL ELSE codeBlock
| IF rval optionalNL codeBlock
Run Code Online (Sandbox Code Playgroud)
在else之前的optionalNL导致3减少/减少.原因是它可以减少使用IfExpr中的第二个规则或者减少到exprLoop,它允许表达式之间有许多换行符.
无论我做什么(我尝试在OptionalNL和ELSE之前编写%prec)它总是减少到exprLoop,哪些情况下bison给我一个关于else的synax错误.我怎么告诉野牛在这一点上转移(到OptionalNL其他)而不是减少?(exprLoop导致else成为错误).
用于测试的示例文件
%%
program:
exprLoop;
exprLoop:
exprLoop2 expr
| exprLoop2
exprLoop2:
| exprLoop2 expr EOS
| exprLoop2 EOS
;
expr:
'i' Var optEOS '{' '}'
| 'i' Var optEOS '{' '}' optEOS 'e' '{' '}'
EOS: '\n' ;
Var: 'v';
optEOS: …Run Code Online (Sandbox Code Playgroud) 我有个问题.
我正在编写一个flex程序,我正在使用这段代码:
%union {
int entero;
char *cadena;
TipoDato tipo;
}
Run Code Online (Sandbox Code Playgroud)
此代码适用于我的数据类型.
我想评估下一行:expresion SUM expresion其中SUM是evaluate的运算和,例如69 + 60
当我写这个
if (($1.tipo == ENT) && ($3.tipo == ENT)){
$$.tipo = ENT;
} else if (($1.tipo == CADEN) && ($3.tipo == CADEN)) {
$$.tipo = CADEN;
} else {
printf ("Error en la suma: Tipos de datos incompatibles Revise los tipos\n");
yyerror(parser);
}
Run Code Online (Sandbox Code Playgroud)
我有下一个错误
../src/buggy.y:350.37-38:$ 1 de`expresion'no tiene tipo declarado
../src/buggy.y:351.28-29:$ 1 de`expresion'no tiene tipo declarado
buggy.tab.c:在函数'yyparse'中:
buggy.tab.c:1646:警告:隐式声明函数'yylex'
../src/buggy.y:顶级:
lex.yy.c:1577:警告:'yyunput'已定义但未使用
lex.yy.c:1618:**警告:'input'已定义但未使用
Leyendo fichero'../ …
我试图寻找这个问题的答案,但似乎找不到一个.我正在尝试使用PLY编写一个Python解析器,用于编写语言.我的BNF的简化版本如下所示:
statement-list -> statement ',' statement-list |
'print' expr
statement -> ident 'was' 'a' type |
ident 'became' expr
type -> 'number' | 'letter'
expr -> factor |
expr '+' factor |
expr '-' factor
factor -> number | letter | ident
Run Code Online (Sandbox Code Playgroud)
其中数字和字母类似于int和char.
Yacc文档(http://www.dabeaz.com/ply/ply.html#ply_nn23)仅显示简单算术表达式的语法,其中明确了p [0]应该是什么.
def p_expression_plus(p):
'expression : expression PLUS term'
p[0] = p[1] + p[3]
Run Code Online (Sandbox Code Playgroud)
我的问题是我如何为我的BNF中的陈述清单做些什么?我有:
def p_statement_list_comma(p):
'statement-list : statement COMMA statement-list'
Run Code Online (Sandbox Code Playgroud)
但我真的不确定下一步该放什么.任何帮助将非常感谢!
野牛抱怨"冲突:1班/减少".我看不出有什么不对.请帮忙.谢谢,
%token OR AND NUMBER
%%
search_condition:
| search_condition AND search_condition { printf(" AND "); }
| '(' search_condition ')'
| predicate
;
predicate:
NUMBER { printf("%d\n", $1); }
;
Run Code Online (Sandbox Code Playgroud) 我正在开发一个有趣的汇编程序,用C,flex,bison编写.我想添加宏,包含和重复块,并考虑使用单独的预处理阶段解析器执行此操作.
我的问题是,我如何跟踪原始源代码行(和文件名)?这用于生成有用的错误消息,漂亮的打印和生成调试信息.
预处理完成后第二个解析器中的yylineno可能会在宏扩展后偏移,依此类推.
我对Lex非常陌生,这个问题的完整要求如下:
编写一个Lex输入文件,该文件将生成一个程序,用于计算文本文件中的字符,单词和行,并报告计数.将单词定义为任何字母和/或数字序列,不带标点符号或空格.标点符号和空格不算作单词.
现在我写下了代码:
%{
#include <stdio.h>
#include <stdlib.h>
int cno = 0, wno = 0, lno = 0; /*counts of characters, words and lines */
%}
character [a-z]
digit [0-9]
word ({character}|{digit})+[^({character}|{digit})]
line \n
%%
{line} { lno++; REJECT; }
{word} { wno++; REJECT; }
{character} { cno++; }
%%
void main()
{ yylex();
fprintf(stderr, "Number of characters: %d; Number of words: %d; Number of lines: %d\n", cno, wno, lno);
return;
}
Run Code Online (Sandbox Code Playgroud)
我用文本文件测试了它:
this is line #1
line #2 is …Run Code Online (Sandbox Code Playgroud) 好的,所以我想我的问题是不言而喻的。
我目前正在Bison中构建一个解析器,并且我想使错误报告更好一些。
目前,我已设置%define parse.error verbose(实际上会发出类似的消息syntax error, unexpected ***********************, expecting ********************。
我只想在错误消息中添加一些更多信息,例如行号(在输入/文件/等位置)
我目前yyerror(没什么...不寻常...大声笑):
void yyerror(const char *str)
{
fprintf(stderr,"\x1B[35mInterpreter : \x1B[37m%s\n",str);
}
Run Code Online (Sandbox Code Playgroud)
聚苯乙烯
%locations指令,该指令很可能与我需要的指令非常接近-但是,我仍然没有找到完整的工作示例,并且不确定如何使用该指令。作为我正在参加的“编译器理论”课程的一项作业,我必须用lex / yacc编码计算器。一些要求是:
如果我尝试输入以下内容:
a=5;
a; // Output: 5
a==5; // Syntax error
Run Code Online (Sandbox Code Playgroud)
但是,如果我输入以下内容,它将起作用:
5==a; // Output: 1
Run Code Online (Sandbox Code Playgroud)
我认为问题在于yacc正在读取a==5的是表格的新赋值,<a> <=> <=5>而不是<a> <==> <5>。我仍然不知道如何解决该问题。我尝试使用%prec注释,但这不能解决问题。
这是代码:calc.l
%{
#include "y.tab.h"
void yyerror(char* s);
%}
%%
"exit" { return exit_command; }
[0-9]+ { yylval.num = atoi(yytext); return number; }
[a-zA-Z] { yylval.id = yytext[0]; return identifier; }
[ \t\n] ;
[-+*/()^%;] { return yytext[0]; }
[<>=!&|] { return yytext[0]; }
. { ECHO; yyerror("Unexpected character"); } …Run Code Online (Sandbox Code Playgroud)