我知道LL与LR解析器的基本区别.我也知道GLR,SLR和LALR都是LR解析器的扩展.所以我的问题更多细节是......
给定一个LL(*)解析器和LR解析器的任何变体,是否有任何语言可以在一个而不是另一个中描述?或者更简单的是,是否有任何功能或属性无法表达?
作为一个具体的例子.如果我要使用LL(*)解析器创建一种语言,我是否会遇到我想要添加到我的语言中的所需功能/属性,这只能通过LR解析器实现(反之亦然)?
programming-languages parser-generator ll-grammar lr-grammar
这不是我的功课,我正在尝试理解LALR(k)语法.所以我找到了这个
S -> aEa | bEb | aFb | bFa
E -> e
F -> e
Run Code Online (Sandbox Code Playgroud)
我制作了一个分析器(在我的git repo中以PDF格式提供LR1notLARL1.pdf
但我无法弄清楚,为什么这个LR语法不是LALR?谁能帮我?谢谢
我目前正在研究编译器,正如我在LR(0)中所理解的,有些情况下我们有"转移/减少"或"减少/减少"冲突,但是不可能发生"转移/转移"冲突!为什么我们不能发生"转变/转变"冲突?
我有一个语法,根据作品的顺序,快乐的报告3减少/减少冲突或没有.我能找到的最小例子是:
%tokentype {Token}
%token
int { Int }
'-' { Neg }
both { Both }
%nonassoc both
%left '-'
%nonassoc NEG
%%
E : int {IntE}
| both E E {BothE $2 $3}
| '-' E %prec NEG {NegE $2}
| E '-' E {SubE $1 $3}
{
data Token = Int | Neg | Both deriving Show
data Expr = BothE Expr Expr | IntE | SubE Expr Expr | NegE Expr deriving Show
}
Run Code Online (Sandbox Code Playgroud)
这有3个减少 - 减少冲突,基于无法区分" …
假设我有这个语法:
A: ?
| B 'a'
B: ?
| B 'b'
Run Code Online (Sandbox Code Playgroud)
什么被认为是项目的关闭A: • B 'a'?
换句话说,在计算闭包时如何处理epsilon转换?
我正在解析一种没有像;. 表达式被定义为最长的标记序列,因此5-5必须解析为减法,而不是解析为两个语句(文字5后跟一元否定-5)。
我使用LALRPOP作为解析器生成器(尽管名称如此,但它是 LR(1) 而不是 LALR,据我所知)。LALRPOP 没有优先级属性,并且默认情况下不像 yacc 那样更喜欢移位而不是归约。我想我了解如何通过构建规则“链”在 LR 语法中编码常规运算符优先级,但我不知道如何将其应用于此问题。
\n预期的解析将是(括号中的各个语句):
\n"5 - 5" \xe2\x86\x92 5-5 instead of 5, -5\n"5 (- 5)" \xe2\x86\x92 5, -5\n"- 5" \xe2\x86\x92 -5\n"5 5" \xe2\x86\x92 5, 5\nRun Code Online (Sandbox Code Playgroud)\n如何更改语法,使其始终更喜欢较长的解析?
\n浏览谷歌结果的前几页以及堆栈溢出并没有针对这个特定问题产生任何结果。大多数相关问题需要更多的前瞻,否则结果是不允许出现没有终止符的连续语句。
\n我创建了一个最小的示例语法来重现移位/归约冲突(该语法中的语句只是一个表达式,在完整的语法中还会有“if”、“while”等以及更多级别的运算符优先级,但是为了简洁起见,我省略了它们)。除了一元减号之外,原始语法中还存在其他冲突,例如print(5),可以将其解析为标识符print和括号内的数字(5)或函数调用。可能还会有更多这样的冲突,但它们都有相同的根本问题,即应该首选较长的序列,但两者目前都是有效的,尽管只有第一个应该有效。
为了方便起见,我创建了一个存储库(签出和cargo run)。语法是:
"5 - 5" \xe2\x86\x92 5-5 instead of 5, -5\n"5 (- 5)" \xe2\x86\x92 5, -5\n"- …Run Code Online (Sandbox Code Playgroud) 我想编写一个解析器生成器用于教育目的,并想知道是否有一些很好的在线资源或教程解释如何编写一个.杰克·克伦肖(Jack Crenshaw)的"让我们编写一个编译器".
我想为LR(1)语法编写解析器生成器.
我对生成动作和goto表背后的理论有了不错的理解,但是想要一些能帮助我实现它的资源.
首选语言是C/C++,Java,即使其他语言也可以.
谢谢.
我有以下语法,我被告知是LR(1)而不是SLR(1):
S :: = a A | b A c | 直流| BDA
A :: = d
我不明白为什么会这样.你会怎么证明这一点?
我对维基百科的以下引用感到困惑:
换句话说,如果一种语言足够合理以允许高效的单遍解析器,则它可以由 LR(k) 语法来描述。并且该语法总是可以机械地转换为等效(但更大)的 LR(1) 语法。因此,从理论上讲,LR(1) 解析方法足以处理任何合理的语言。在实践中,许多编程语言的自然语法接近 LR(1)。[需要引用]
这意味着如果能够将语法转换为语法,则解析器生成器(如bison)将非常强大(因为它可以处理LR(k)语法)。是否存在一些这样的例子,或者如何做到这一点的秘诀?我想知道这一点,因为我的语法中有移位/归约冲突,但我认为这是因为它是一种语法,并且想将其转换为语法。附带问题:是一种不合理的语言,因为我读过,生成的解析器无法解析它。LR(k)LR(1)LR(2)LR(1)C++bison
lr-grammar ×10
parsing ×7
grammar ×4
bison ×1
compilation ×1
conflict ×1
epsilon ×1
happy ×1
haskell ×1
lalr ×1
ll-grammar ×1
rust ×1