有没有人知道包含典型编译器课程的在线课程/大学讲座?我有计算理论但不幸的是我的学校没有提供编译器构建课程.
我知道那里有讲座; 我希望能为特别好的产品提供建议.
还有新手到现场的书吗?除了龙书之外,至少还有一些东西.初学者水平很好,我知道市场上有很多中级高级文本.
谢谢!
我正在阅读Java语言规范8.
我试图理解第2章.语法.
这是我已经学到的:
语义学:
语义学是对意义的研究.
含义:
在语义中,含义被定义为扩展:世界中单词/短语所指的东西,加上意图:单词/短语唤起的概念/心理图像.
语法:
语法是关于句子的结构,以及决定哪些单词去哪里的内容.
生产:
计算机科学中的生产或生产规则是指定符号替换的重写规则,可以递归地执行符号替换以生成新的符号序列.
字母:
非空集在被指示用于字符串操作时称为字母表.
Lexeme:
lexeme是一串字符,形成一个句法单位.
句法单位:
句子是"最高"(即最大)的句法单位,
最低(即最小)的句法单位是单词,
中间句法单位是短语.
令牌:
令牌是表示词汇的结构,该词汇明确指出其用于解析的分类.
语法:
语法(当没有给出上下文时,为了清楚起见通常称为正式语法)是一组用于正式语言的字符串的生成规则.规则描述了如何根据语言的语法从语言的字母表中形成有效的字符串.形式语法是一组用于重写字符串的规则,以及重写开始的"起始符号".
我无法找出语法语法是什么.
我正在尝试编写正则表达式引擎.我想手工写一个递归下降解析器.没有正则表达式语言(不是正则表达式可以描述的语言)的左递归的无上下文语法会是什么样的?是否最容易重新分解语法糖,即a+改为aa*?提前致谢!
给出以下语法
S -> L=L
s -> L
L -> *L
L -> id
Run Code Online (Sandbox Code Playgroud)
非终端的第一个和后续是什么?
如果语法改为
S -> L=R
S -> R
L -> *R
L -> id
R -> L
Run Code Online (Sandbox Code Playgroud)
什么是第一个并遵循?
语法定义包含产品,非常简单的语法示例:
E -> E + E
E -> n
Run Code Online (Sandbox Code Playgroud)
我想在c#中实现语法类,但我不确定如何存储产品,例如如何区分终端和非终端符号.我在考虑:
struct Production
{
String Left; // for example E
String Right; // for example +
}
Run Code Online (Sandbox Code Playgroud)
Left将始终是非终端符号(它是关于无上下文的语法)但是生产的右侧可以包含终端和非终端符号
所以现在我想到了两种实现方式:
非终端符号将使用括号编写,例如:
E + E将表示为字符串"[E] + [E]"
创建其他数据结构NonTerminal
struct NonTerminal {String Symbol; }
和E + E将表示为数组/列表:
[new NonTerminal("E"), "+", new NonTerminal("E")]
Run Code Online (Sandbox Code Playgroud)
但是认为有更好的想法,听到一些回应会很有帮助
我正在将无上下文语法转换为Greibach Normal Form(GNF).主要转换(来自Hopcroft和Ullman)是对语法的索引变量的迭代序列.它本质上是"无国籍的".我已经将它实现为适当索引的一系列折叠(实现相当简单):
gnf :: Ord a => Set (Rule a) -> Set (Rule a)
gnf rl = foldl step1 rl [1..maxIndex rl]
where step1 rl' k = foldl step2 rl' [1..k - 1]
where step2 rl'' j = noLR k (subst rl'' k j)
Run Code Online (Sandbox Code Playgroud)
maxIndex rl返回一组规则中的最大变量索引; subst rl kj通过右侧以j -indexed变量开头的规则对k- indexed规则执行替换.执行gnf后,我需要以相反的顺序对语法执行最后一次传递.
问题是noLR,它使用左递归k - indexed规则转换语法.这是一个"状态"功能,因为唯一的变量必须为每个规则(或生成ķ -indexed规则),其noLR被应用.所以我写了一个有状态函数
noLR :: Ord a => Int -> Set (Rule a) -> State …Run Code Online (Sandbox Code Playgroud) 可能重复:
c的哪个版本是用于返回有效值的括号内的块?
以下是典型MAX宏的类型安全版本(适用于gcc 4.4.5):
#define max(a,b) \
({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a > _b ? _a : _b; })
Run Code Online (Sandbox Code Playgroud)
在这里,我们看到这个表达式max(a,b)返回表达式的结果
_a > _b ? _a : _b;
Run Code Online (Sandbox Code Playgroud)
即使这个表达式是一个块.所以,我调查过,发现这是有效的C:
int a = ({123;}); // a is 123
Run Code Online (Sandbox Code Playgroud)
有人可以解释为什么这是有效的语法和({statements})的真实行为是什么?另外,您会注意到{123;}不是有效的表达式,而只是({123;}).
考虑以下对无上下文语法的扩展,该语法允许规则在左侧,非终端右侧的一个(或多个)终端.也就是说,形式的规则:
A b -> ...
Run Code Online (Sandbox Code Playgroud)
右侧可以是任何东西,例如在无上下文的语法中.特别是,不要求右侧的末端具有完全相同的终端符号.在这种情况下,此扩展将是上下文相关的.但终端不仅仅是一个背景.有时,这个终端被称为"后推".
显然,这不再是CFG(类型-2).它包括类型1.但它是什么?真的输0了吗?
Prolog 中的Definite Clause Grammars dcg允许这种特殊的扩展.(为了避免误解,我在这里不考虑Prolog的完整扩展.即我假设终端来自有限的字母而不是任意的术语,我也不认为Prolog在DCG中允许的其他参数,这些参数也属于类型 - 已经0了.)
编辑:这是一种更简单的描述扩展的方法:添加到表单的CFG规则
A b -> <epsilon>
Run Code Online (Sandbox Code Playgroud) 我正在学习问题中的引理之间的区别.我能找到的每个引用都使用了这个例子:
{(a^i)(b^j)(c^k)(d^l) : i = 0 or j = k = l}
Run Code Online (Sandbox Code Playgroud)
显示两者之间的差异.我可以找到一个使用常规引理来"反驳"它的例子.
选择w = uvxyz,st | vy | > 0,| vxy | <= p.假设w包含相等数量的b,c,d's.
我选择了:
u,v,x = ?
y = (the string of a's)
z = (the rest of the string w)
Run Code Online (Sandbox Code Playgroud)
抽取y只会增加a的数量,如果| b | = | c | = | d | 起初,它现在还会.
(类似的论据,如果w没有a.那么只需抽出你想要的任何东西.)
我的问题是,奥格登的引理如何改变这一策略?"标记"有什么作用?
谢谢!
这可能与我不理解关键字提取功能有关,从文档来看,该功能似乎是为了避免关键字和以下表达式之间不存在空格的问题。但是假设我有一个相当标准的变量名、函数名等标识符正则表达式:
/\w*[A-Za-z]\w*/
如何防止它与保留关键字(例如IForELSE或类似的东西)匹配?所以这个表达式会产生错误:
int IF = 5;
虽然这不会:
int x = 5;