我们不知道如何跟踪 yacc 解析器中的错误。yylineno我们尝试在 lex 文件中使用并尝试添加%option yylineno,但它仍然不起作用,我们无法在 yacc 中访问这些变量。
error我们想要的只是使用yacc 和行号打印出语法错误。
这是我们的.l文件
%{
#include <stdio.h>
#include <stdlib.h>
#include "y.tab.h"
int yylineno=1;
%}
%option yylineno
identifier [a-zA-Z_][a-zA-Z0-9_]*
int_constant [0-9]+
delimiter ;
%%
"int" {return INT;}
{int_constant} return INT_CONST;
{identifier} return IDENT;
\= {return ASOP;}
\+ {return PLUS;}
\- {return MINUS;}
\* {return MULT;}
\/ {return DIV;}
\, {return COMMA;}
\( {return OP;} /*OP CP = Opening Closing Parenthesis*/
\) {return CP;}
\[ {return OB;} /*OB …Run Code Online (Sandbox Code Playgroud) 我正在用yacc / bison编写一个简单的计算器。
表达式的语法看起来有点像这样:
expr
: NUM
| expr '+' expr { $$ = $1 + $3; }
| expr '-' expr { $$ = $1 - $3; }
| expr '*' expr { $$ = $1 * $3; }
| expr '/' expr { $$ = $1 / $3; }
| '+' expr %prec '*' { $$ = $1; }
| '-' expr %prec '*' { $$ = $1; }
| '(' expr ')' { $$ = …Run Code Online (Sandbox Code Playgroud) 我认为 Bison 和 Yacc 经常用于解析编程语言的语法。(以及用于标记化的 lex/flex...)
我的问题是:所有编译器都是用这个工具制作的还是有人从头开始编写解析器?(我主要是在没有“编译器编译器”的情况下完成的,但我知道它们)
在没有这些工具的情况下构建解析器是否“有利可图”?
yacc/bison 和 lex/flex 是否有更“开放”且不那么严格的替代方案。是否存在 C 库可以为我做这件事(解析)?是否有另一种选择可以在没有 yacc 的情况下构建解析器,但也不从头开始编写它?
最好的问候卢卡斯
我在这里查看calc源http://epaperpress.com/lexandyacc/
我在calc.y中看到了这些行
| expr '+' expr { $$ = opr('+', 2, $1, $3); }
| expr '-' expr { $$ = opr('-', 2, $1, $3); }
| expr '*' expr { $$ = opr('*', 2, $1, $3); }
| expr '/' expr { $$ = opr('/', 2, $1, $3); }
| expr '<' expr { $$ = opr('<', 2, $1, $3); }
| expr '>' expr { $$ = opr('>', 2, $1, $3); }
Run Code Online (Sandbox Code Playgroud)
有没有办法将它们分组?所以我可以写下面的东西而不是?
| expr mathOp expr …Run Code Online (Sandbox Code Playgroud) R有这样的解析工具吗?它不一定是我的案例的lex/yacc兼容工具.
(我是R新手)
编辑:我对使用R实现另一种语言感兴趣
我想知道如何在用ocamlyacc和ocamllex编写语法时处理语句中的变量引用.
问题是表格的陈述
var x = y + z
var b = true | f;
Run Code Online (Sandbox Code Playgroud)
应该是正确的,但在第一种情况下,变量引用数字,而在第二种情况下,f变量是布尔变量.
在我写的语法中我得到了这个:
numeric_exp_val:
| nint { Syntax.Int $1 }
| FLOAT { Syntax.Float $1 }
| LPAREN; ne = numeric_exp; RPAREN { ne }
| INCR; r = numeric_var_ref { Syntax.VarIncr (r,1) }
| DECR; r = numeric_var_ref { Syntax.VarIncr (r,-1) }
| var_ref { $1 }
;
boolean_exp_val:
| BOOL { Syntax.Bool $1 }
| LPAREN; be = boolean_exp; RPAREN { be } …Run Code Online (Sandbox Code Playgroud) 我正在使用ocamllex/yacc在ocaml中编写编译器.事情进展顺利,但我遇到了设计问题.对于我创建的每个AST节点,最好在源代码中获得有关该节点的行/字符位置的信息.这对于稍后向用户提供错误消息将是有用的.
现在,我可以为我的节点添加某种元类型:
type node = Node1 of ... * meta | Node2 of ... * meta
Run Code Online (Sandbox Code Playgroud)
但这似乎是多余的.后来,当我完成验证AST时,我将不得不写
match n with
| NodeX(..., _) -> ...
Run Code Online (Sandbox Code Playgroud)
在每match一个浪费空间的地方.
解决这个问题的最佳方法是什么?
我正在尝试一个可以进行浮点运算的flex/bison计算器.我的flex代码看起来像这样
%{
#include "calc.tab.h"
#include <stdlib.h>
void yyerror(char *s);
%}
digit [0-9]
integer {digit}+
real ({digit}+[.]{digit}*)|({digit}*[.]{digit}+)
exp ({integer}|{real})[eE]-?{integer}
%%
({integer}|{real}|{exp}) { yylval = atof(yytext); return NUMBER; }
[-+*/\n] { return *yytext; }
[ \t\v\f\r] { }
. { yyerror("Unknown Character"); }
%%
int yywrap(void)
{
return 1;
}
Run Code Online (Sandbox Code Playgroud)
我的野牛代码看起来像这样
%{
#include <stdio.h>
typedef double YYSTYPE;
#define YYSTYPE_IS_DECLARED
void yyerror(char *s);
extern char *yytext;
extern int yylineno;
%}
%token NUMBER
%left '+' '-'
%left '*' '/'
%%
program: program expr '\n' …Run Code Online (Sandbox Code Playgroud) yytext [0]是什么意思?我们为什么要在lex和yacc程序中使用?我是学习者所以不要介意这是一个愚蠢的问题.
我试图运行PLY的一个简单例子的第一部分,但我遇到了一个奇怪的错误.当我运行以下代码时,它给我一个关于lex.lex()的错误任何人都知道问题是什么?
import ply.lex as lex
tokens = [ 'NAME','NUMBER','PLUS','MINUS','TIMES', 'DIVIDE', 'EQUALS' ]
t_ignore = '\t'
t_PLUS = r'\+'
t_MINUS = r'-'
t_TIMES = r'\*'
t_DIVIDE = r'/'
t_EQUALS = r'='
t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
def t_NUMBER(t):
r'\d+'
t.value = int(t.value)
return t
lex.lex() # Build the lexer
Run Code Online (Sandbox Code Playgroud)
这是错误:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-2-e527bd224769> in <module>()
14 return t
15
---> 16 ply.lex.lex() # Build the lexer
c:\python27\lib\site-packages\ply\lex.pyc in lex(module, object, debug, optimize, lextab, reflags, nowarn, outputdir, debuglog, errorlog) …Run Code Online (Sandbox Code Playgroud)