我试图找出在使用lex/yacc(flex/bison)时如何显示消息/提示.
例如,main看起来像这样:
int main(int argc, char *argv[])
{
yyparse();
}
Run Code Online (Sandbox Code Playgroud)
其中调用yacc,调用yylex().这会产生一个等待STDIN的空白行.我怎样才能显示如...的消息
message $ _
代替
_
下划线表示光标位置,等待STDIN的输入......
忘了提,我想重复打印的提示......所以在每次lex/yacc请求从stdin输入之前...
我有一个用ocamlyacc和ocamllex编写的解析器和词法分析器.如果要解析的文件过早结束,就像在行末尾忘记分号一样,应用程序不会引发语法错误.我意识到这是因为我正在提高并捕获EOF,这使得词法分析器忽略了未完成的规则,但是我应该怎么做才能引发语法错误?
这是我当前的解析器(简化),
%{
let parse_error s = Printf.ksprinf failwith "ERROR: %s" s
%}
%token COLON
%token SEPARATOR
%token SEMICOLON
%token <string> FLOAT
%token <string> INT
%token <string> LABEL
%type <Conf.config> command
%start command
%%
command:
| label SEPARATOR data SEMICOLON { Conf.Pair ($1,$3) }
| label SEPARATOR data_list { Conf.List ($1,$3) }
| label SEMICOLON { Conf.Single ($1) }
label :
| LABEL { Conf.Label $1 }
data :
| label { $1 }
| INT { Conf.Integer …Run Code Online (Sandbox Code Playgroud) 我正在开发一个班级项目,我们必须在其中构建一个解析器。我们目前正处于在 yacc 中构建解析器的阶段。目前让我困惑的是我读到您需要为每个非终结符分配一个类型。在某些情况下,我会有类似的东西:
...
%union {
Type dataType;
int integerConstant;
bool boolConstant;
char *stringConstant;
double doubleConstant;
char identifier[MaxIdentLen+1]; // +1 for terminating null
Decl *decl;
List<Decl*> *declList;
}
%token <identifier> T_Identifier
%token <stringConstant> T_StringConstant
%token <integerConstant> T_IntConstant
%token <doubleConstant> T_DoubleConstant
%token <boolConstant> T_BoolConstant
...
%%
...
Expr : /* some rules */
| Constant { /* Need to figure out what to do here */ }
| /* some more rules */
;
Constant : T_IntConstant { $$=$1 }
| …Run Code Online (Sandbox Code Playgroud) 仍在学习 yacc 和 flex,并遇到了我的操作方法和教程未涵盖的场景。我正在尝试解析一个文件,并且在进行过程中,我正在对放置在文件中的代码进行一些辅助错误检查parser.y。当我遇到字典顺序正确(即解析正确匹配)但逻辑不正确(意外值或不适当值)的内容时,我该如何退出yyparse?另外,我可以让它返回一个错误代码给我,我可以在我的调用代码中检查吗?
/* Sample */
my_file_format:
header body_lines footer
;
header:
OBRACE INT CBRACE
|
OBRACE STRING CBRACE {
if ( strcmp ( $1, "Contrived_Example" ) != 0 ) { /* I want to exit here */ }
}
;
/* etc ... */
Run Code Online (Sandbox Code Playgroud)
我意识到在我的示例中,我可以简单地使用规则查找“Contrived_Example”,但我的观点在if- 块中 - 我可以告诉我yyparse我想在这里停止解析吗?
我相信我无法理解轮班减少冲突的工作方式.我知道野牛可以向前看,所以我不明白我为什么会遇到这个问题.
在我的语言中,List被定义为[]之间的一组数字或列表.例如[] [1] [1 2] [1 [2] 3]都是有效列表.
以下是导致问题的定义
value: num
| stringValue
| list
;
list: LEFTBRACE RIGHTBRACE
| LEFTBRACE list RIGHTBRACE
| num list
| RIGHTBRACE
;
Run Code Online (Sandbox Code Playgroud)
冲突发生在数字上,它不知道按列表规则移动的天气,或者通过值规则减少.我很困惑,因为它无法检查列表是否跟随该号码?
任何关于如何进行的煽动都将不胜感激.
我正在阅读一个文件,由于某种原因,当我尝试一个表达式时,我得到一个语法错误5+5,如果我这样做,5 + 5它工作得很好.我很困惑为什么会这样做?
这是我的lex文件(我将遗漏读取文件的主文件):
%{
#include "y.tab.h"
#include "stdio.h"
#include <stdlib.h>
%}
%%
(\/\*([^*]|(\*+([^*/]|[\r\n])))*\*+\/)+ {}
\/\/[^\n]*\n {}
fd { return FD; }
[\r\t\n]+ {}
[ ]* {}
bk { return BK;}
setc {return SETC;}
[-+]?[0-9]+ { yylval = atoi(yytext); return NUMBER;}
fd[0-9]+ { }
rt {return RT;}
pink {return COLOR_TYPE;}
magenta {return COLOR_TYPE; }
if {return IF; }
ifelse {return IFELSE; }
\[ {return LBRACKET; }
\] {return RBRACKET; }
\< {return LESS_THAN; }
\> {return …Run Code Online (Sandbox Code Playgroud) 我想在 my 中使用YY_BUFFER_STATE yy_scan_string(const char *str)和其他功能,我做了以下事情:yyparse()main.cpp
extern "C"{
extern YY_BUFFER_STATE yy_scan_string(const char *str);
}
Run Code Online (Sandbox Code Playgroud)
但是有一个错误error:YY_BUFFER_STATE' does not name a type`,然后我做了:
extern yy_buffer_state;
typedef yy_buffer_state *YY_BUFFER_STATE;
extern int yyparse();
extern YY_BUFFER_STATE yy_scan_buffer(char *, size_t);
Run Code Online (Sandbox Code Playgroud)
但是同样的问题,怎么办,谢谢,非常感谢您的帮助!!
这是 main.cpp 文件。#include "main.h"
#include <string.h>
extern "C"{void scan_string(const char* str);}
int yyparse();
void test::getvalue(int& var)
{
if (var!=0)
std::cout<<"True"<<std::endl;
else
std::cout<<"False"<<std::endl;
}
int main(){
std::string str="T+F";
//how to send str as an Input to parse?
yyparse();
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我在野牛中创建了上下文无关文法,在Flex中创建了扫描仪。现在我还想进行语义检查,例如,假设输入是这样的:
int m=5;
c=c+5;
Run Code Online (Sandbox Code Playgroud)
该输入在语法上是正确的,但是使用了一个未声明的变量,即“ c”。我该如何进行语义检查?我应该从哪里开始?我应该用flex还是野牛写代码?如果有人可以提供帮助,我深表感谢。谢谢。
compiler-construction yacc bison semantic-analysis flex-lexer
许多编程语言都有以行结尾终止的语句。但是,通常情况下,如果解析器无法理解该行,则在语句中间允许行结尾;例如,
a = 3 +
4
Run Code Online (Sandbox Code Playgroud)
...将在 Ruby 和 Python* 中解析为 statement a = 3+4,因为a = 3+没有任何意义。换句话说,换行符会被忽略,因为它会导致解析错误。
我的问题是:如何使用标记器和解析器简单/优雅地完成相同的行为?我使用 Lemon 作为解析器生成器,如果它有任何不同的话(尽管我也将这个问题标记为 yacc,因为我确定该解决方案同样适用于两个程序)。
这是我现在的做法:在没有句法歧义的任何情况下,允许可选地出现语句终止符。换句话说,像
expression ::= identifier PLUS identifier statement_terminator.
expression ::= identifier PLUS statement_terminator identifier statement_terminator.
Run Code Online (Sandbox Code Playgroud)
...换句话说,可以在加号后使用换行符,因为这不会对语法的歧义产生任何影响。我担心这会增加语法的大小,我有很多机会遗漏案例或在语法中引入细微的错误。有没有更简单的方法来做到这一点?
编辑*:实际上,该代码示例不适用于 Python。但是,如果您传入这样的内容,Python 实际上会忽略换行符:
print (1, 2,
3)
Run Code Online (Sandbox Code Playgroud) 我是lex和yacc以及编译器设计的新手.我想知道在哪个阶段(词法,句法或任何其他阶段)以及如何生成符号表?
我是否可以简要描述y.output文件,该文件是通过给yacc提供-v选项生成的.我试图查看它但没有得到太多信息.
我能否知道除了编译器设计之外还使用lex和yacc的其他应用程序.