我有一个BNF和EBNF的语法.BNF显然更加冗长.就使用BNF构建递归下降解析器而言,我有一个相当不错的想法; 这有很多资源.我无法找到将EBNF转换为递归下降解析器的资源.这是因为它更难吗?我从我的CS理论课中回忆起我们讨论过EBNF,但是我们没有将它们转换成递归下降的解析器.我们确实将BNF转换为递归下降解析器.
我问的原因是因为EBNF更紧凑.
从一般的EBNF看,我注意到在{和之间包含的术语}可以转换成while循环.还有其他指导方针或规则吗?
这是一个特定于parboiled解析器框架和一般BNF/PEG的问题.
假设我有一个相当简单的正则表达式
^\\s*([A-Za-z_][A-Za-z_0-9]*)\\s*=\\s*(\\S+)\\s*$
Run Code Online (Sandbox Code Playgroud)
代表伪EBNF
<line> ::= <ws>? <identifier> <ws>? '=' <nonwhitespace> <ws>?
<ws> ::= (' ' | '\t' | {other whitespace characters})+
<identifier> ::= <identifier-head> <identifier-tail>
<identifier-head> ::= <letter> | '_'
<identifier-tail> ::= (<letter> | <digit> | '_')*
<letter> ::= ('A'..'Z') | ('a'..'z')
<digit> ::= '0'..'9'
<nonwhitespace> ::= ___________
Run Code Online (Sandbox Code Playgroud)
如何在EBNF中定义非空白(一个或多个不是空格的字符)?
对于熟悉Java parboiled库的人,如何实现定义非空白的规则?
我正在为我的PEG解析器添加零或多和一个或多个修饰符,这很简单,因为PEG中的回溯非常少.之前的迭代从未被重新考虑过,因此简单的while循环就足够了.
但是,在其他情况下,零或多和一个或多个修饰符确实需要回溯.例如,采用以下正则表达式:
(aa|aaa)+
Run Code Online (Sandbox Code Playgroud)
这种表达应该能够贪婪地匹配七串a的:有几种方式加起来2和3得到7.但到那里,重新考虑早期迭代是必要的.例如,如果表达式a第一次匹配三个,第二次匹配三个a,则只剩下一个a,这是无法匹配的.然而,回溯过去的三个a并匹配两个a,而五个a匹配.然后最后两个a也可以匹配(即3 + 2 + 2 = 7).
幸运的是,正则表达式在匹配字符串后退出搜索.但是EBNF解析器怎么样?如果语法不明确,解析器将使用回溯来查找所有可能的语法树!如果我们有生产
( "aa" | "aaa" )*
Run Code Online (Sandbox Code Playgroud)
一个七字符串a,一个完全回溯解析器将返回所有可能的方式表达7在2和3方面.而这只是七个a:匹配一个稍长的字符串,并且N -ary树的可能性增长另一个层次.考虑N = 6:
S : ( T )*
;
T : A
| B
| C
| D
| E
| F
;
Run Code Online (Sandbox Code Playgroud)
一个可怕的组合爆炸!
但是真的可以这样吗?EBNF中的零或多和一个或多个修饰符没有限制吗?如上所述实现它们比while()PEG解析器的普通循环要多得多,所以我不得不怀疑......
我正在使用EBNF来定义语法.
但是我被困了因为我需要定义一个排列:我有一组可以组合的值,但它们只能使用一次而我不关心顺序.
如何使用EBNF?
示例:值:a,b,c
可能的组合:abc,acb,bac,bca,cab,cba
我试图找出任何数学表达式的语法规则。
我正在使用 EBNF(下面链接的维基文章)来导出语法规则。
我设法想出了一个已经工作了一段时间的方法,但是语法规则失败了onScreenTime + (((count) - 1) * 0.9)。
规则如下:
math ::= MINUS? LPAREN math RPAREN
| mathOperand (mathRhs)+
mathRhs ::= mathOperator mathRhsGroup
| mathOperator mathOperand mathRhs?
mathRhsGroup ::= MINUS? LPAREN mathOperand (mathRhs | (mathOperator mathOperand))+ RPAREN
Run Code Online (Sandbox Code Playgroud)
您可以安全地假设mathOperand是正数或负数或变量。您还可以假设mathOperator表示任何数学运算符,例如 + 或 -。
另外,LPAREN和RPAREN分别是“(”和“)”。
EBNF: https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_Form
编辑
忘记提及它失败了(count) - 1。它说RPAREN预期而不是- 1。
编辑 2我修改后的 EBNF 现在看起来像这样:
number ::= NUMBER_LITERAL //positive integer
mathExp ::= term_ ((PLUS …Run Code Online (Sandbox Code Playgroud) 我对 VHDL 中实体的语法感到困惑。以下是EBN 表格中应如何声明实体的规则:
资料来源:Peter J. Ashenden,“VHDL 设计师指南”,第 3 版,Morgan Kaufmann,2008 年。
我感到困惑的是声明的结尾。据此,我不需要在最后包含实体或标识符,一切都会一样。例如,下面的两个声明是一样的吗?
声明 1
entity identifier is
...
begin
...
end ;
Run Code Online (Sandbox Code Playgroud)
声明2
entity identifier is
...
begin
...
end entity identifier ;
Run Code Online (Sandbox Code Playgroud)
如果是,为什么有人会选择后一种声明?有没有建议我应该使用这两种变体中的哪一种?我问这个是因为我通常在示例中看到后一个声明,我无法解释为什么有人更喜欢第二个声明而不是第一个声明。
I'm using lark, an excellent python parsing library.
It provides an Earley and LALR(1) parser and is defined through a custom EBNF format. (EBNF stands for Extended Backus–Naur form).
Lowercase definitions are rules, uppercase definitions are terminals. Lark also provides a weight for uppercase definitions to prioritize the matching.
I'm trying to define a grammar but I'm stuck with a behavior I can't seem to balance.
I have some rules with unnamed literals (the strings or characters …
我宁愿不自己创建语法。我确实下载了一个“语法”,但它是用 ANTLR 或 Yacc 的非标准形式编写的,并且包含词法分析器语句。我需要一些时间将两者分开并为解析器生成器引入正确的语法。
我正在为我的编程语言和编译器课程写一篇关于 J 编程语言的论文。由于它是一种相对未知(但很有趣)的编程语言,因此我无法找到有关 (E)BNF 中 J 的形式语法的正确文档和信息,J 的一些开源实现,尤其是词法分析器和解析器。
有谁知道J 编程语言的(E)BNF的准确来源?如果是这样,那是LL 语法吗,它可以“通过”解析器生成器吗?
例如:
* (describe 'do)
Run Code Online (Sandbox Code Playgroud)
...
Documentation:
DO ({(Var [Init] [Step])}*) (Test Exit-Form*) Declaration* Form*
Run Code Online (Sandbox Code Playgroud)
这个文档模板中的星星是什么意思?
ebnf ×10
grammar ×4
parsing ×4
bnf ×3
syntax ×2
backtracking ×1
common-lisp ×1
expression ×1
fpga ×1
j ×1
java ×1
lark-parser ×1
lisp ×1
ll-grammar ×1
parboiled ×1
permutation ×1
python ×1
regex ×1
sql ×1
vhdl ×1