语法转换为Lex/Yacc
Grammar to Lex/Yacc
我已经被分配了一个项目,涉及到我使用一个语法(以BNF形式)并创建一个词法扫描程序(使用lex)和一个解析器(使用bison)。我从来没有使用过这些程序,我认为一个很好的参考是看看这些项目是如何从语法中创建的。我正在寻找一个语法,它的关联。l和。ypp文件,最好在c++。我已经能够找到示例文件或示例语法,但不是两者都能找到。我花了些时间找,但什么也没找到。我想我应该贴在这里,希望有人能给我一些东西,但我将继续寻找在此期间。
我正在读Tom Niemann的书http://epaperpress.com/lexandyacc/download/LexAndYaccTutorial.pdf这似乎写得很好,可以理解。
感谢编辑:我还在寻找,我开始认为我正在寻找的不存在。谷歌通常不会让我失望!
编辑2:也许如果我提供一些语法,你们可以告诉我合适的。l和。ypp文件是什么样子的。这只是语法的一小部分,我只需要稍微"尝尝"一下它是如何工作的,我想我可以从那里开始。 语法:Program ::= Compound
Statements ::= Compound | Assignment | ...
Assignment ::= Var ASSIGN Expression
Expression ::= Var | Operator Expression Expression | Number
Compound := START Statements END
Number ::= NUMBER
描述:
Assignment is the equal sign ":="
Var is an identifier that begins with a lower case letter and is followed by lower case letters or digits
START is the "start" keyword
END is the "end keyword
Operator is "+", "-", "*", "/"
Number is decimal digits which could potentially be negative (minus sign in front)
大部分操作都相当简单。然而,有一部分显然有问题。您已经定义了一个数字(可能)包含一个前导-
,这是一个问题。
这个问题很简单。给定像321-123
这样的输入,词法分析器(通常不会跟踪当前状态)基本上不可能猜测这是两个令牌(321
和-123
还是三个321
, -
, 123
)。在这种情况下,-
几乎肯定是打算与123
分开的,但如果输入是321 + -123
,您显然希望将-123
作为单个令牌。
-
不是数字的一部分。相反,您总是希望将-
视为一个运算符,并且该数字本身仅由数字组成。然后由解析器来对-
是一元还是二进制的表达式进行排序。
考虑到这一点,词法分析器文件看起来像这样:
%{
#include "y.tab.h"
%}
%option noyywrap case-insensitive
%%
:= { return ASSIGN; }
start { return START; }
end { return END; }
[+/*] { return OPERATOR; }
- { return MINUS; }
[0-9]+ { return NUMBER; }
[a-z][a-z0-9]* { return VAR; }
[ rn] { ; }
%%
void yyerror(char const *s) { fputs(s, stderr); }
匹配的yacc文件看起来像这样:
%token ASSIGN START END OPERATOR MINUS NUMBER VAR
%left '-' '+' '*' '/'
%%
program : compound
statement : compound
| assignment
;
assignment : VAR ASSIGN expression
;
statements :
| statements statement
;
expression : VAR
| expression OPERATOR expression
| expression MINUS expression
| value
;
value: NUMBER
| MINUS NUMBER
;
compound : START statements END
%%
int main() {
yyparse();
return 0;
}
注意:我只测试了这些极其最低限度-足以验证我认为是语法的输入,例如:start a:=1 b:=2 end
和start a:=1+3*3 b:=a+4 c:=b*3 end
被接受(没有打印出错误消息)和我认为是不语法的输入,例如:9:=13
和a=13
做都打印出syntax error
消息。因为这并没有尝试对表达式做更多的事情,只是识别那些符合或不符合语法的表达式,这是我们所能做的最好的了。
- 野牛/yacc 解析器在不被空格分隔时跳过 grammer - "unexpected $end"
- 解释通过 lex/flex 实现 C/C++嵌套的"#include "Header""语法?
- 为什么要提升精神 lex 挂而不是解析错误?
- Yacc/flex 语法错误
- makefile 和 lex+yacc 中的错误 -> 错误:"noyywrap"未声明(在此函数中首次使用)
- 混合多个 lex/yacc 组合
- 如何在 lex 中捕获多行
- [lex.ccon] 中 c-char 的定义可能存在矛盾
- YACC递归中的con缩值
- 如何阻止Lex为每个规则输出到thevest to stdout
- 与 IPv4 点分十进制表示法匹配的 lex 模式
- loop问题中的yacc/lex yyparse()
- 如何将 API 从 lex yacc 设置为程序
- 编译错误.如何使用lex / yacc解析变量名称
- 使用 lex 和 yacc 解析文件的C++程序中的编译错误
- 如何从lex / yacc获取更多解析错误信息
- 为什么不能使用 LEX/YACC 来解析编译器的C++?
- 语法转换为Lex/Yacc
- 使用lex和yacc打印令牌
- Lex/Yacc解析器解析在列中具有头和值的文件