作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
昨天我问了语法,今天在Java中,我正在学习如何使用我完成的词法分析器中的标记来实现解析语法的算法。
对于这个问题,我需要一个人来检查我的理解。
让我们假设给定Scheme语法:
exp -> ( rest
| #f
| #t
| ' exp
| integer_constant
| string_constant
| identifier
rest -> )
| exp+ [ . exp ] )
Node parseExp() {
check to see if the token is left parenthesis
if true, return a node for Cons (which is a non-terminating node in Scheme
parse tree) and call parseRest()
else check to see if the token is #f
if true, return a node for Boolean with stored value #f
else check to see if the token is #t
if true, return a node for Boolean with stored value #t
else check to see if the token is quote
if true, return a node for Quote and recursively call parseExp()
else check to see if the token is integer_constant
if true, return a node for Integer with stored value int
else check to see if the token is string_constant
if true, return a node for String with stored string value
else check to see if the token is identifier
if true, return a node for identifier with stored string value
else
print error message saying a Syntax error occured
return null
}
Node parseRest() {
check to see if the token is right parenthesis
if true, return a node for Nil (which is a terminating () node in scheme
parse tree)
else // I am having difficulty trying to put this into an algorithm here
call parseExp() for the first expression
while (token does not equal right parenthesis) {
getNextToken()
if (token equals right parenthesis)
return a node for right parenthesis
else if (token equals dot)
return a node for dot
getNextToken()
if (token equals right parenthesis)
print error message saying a Syntax error occurred
return null
else
call parseExp()
else
parseExp()
}
}
最佳答案
您走在正确的道路上,但存在一些问题:
check to see if the token is left parenthesis
if true, return a node for Cons (which is a non-terminating node in Scheme
parse tree) and call parseRest()
parseRest()
的结果执行什么操作,但是我假设您想将其存储在Cons节点中。这样做的问题是Cons节点应该有两个子节点(如果列表是列表的开头,列表的尾部则是一个子节点-如果不清楚,则可能必须查看Scheme语言的规则),但parseRest仅给您一个节点,因此不起作用。因此,让我们退后一步,想一想
(
时想要什么:
(
是对的开始(即点对或非空列表),或者是空列表
()
。在第一种情况下,我们想要一个Cons节点,但是在第二种情况下,我们想要一个Nil节点,因为空列表不是cons单元。因此,我们有两种可能性,在查看了列表的其余部分之前,我们不知道该选择哪一种。因此,不应在此处做出决定,而应在parseRest函数内部做出决定。因此,我们将代码更改为:
check to see if the token is left parenthesis
if true, return the result of parseRest()
Cons(Ident("x"), Nil)
。
Cons(Ident("x"), Ident("y"))
。
Cons(Ident("x"), Cons (Ident("y"), Nil))
。
Cons(Ident("x"), Cons (Ident("y"), Ident("z")))
。
)
,我们将返回
Nil
。同样,这已经在您的代码中起作用了。否则,我们将解析一个表达式(如果此处没有有效的表达式,则会出现错误)。那之后会发生什么呢?好吧,如果我们找到一个表达式,则该表达式是Cons单元的第一个元素。所以我们要返回
Cons(theExpression, ...)
。但是
...
部分有什么内容?好吧,这取决于下一个令牌是否为点。如果是点,则我们有一个点表达式,因此点后需要一个表达式,我们想返回
Cons(theExpressionBeforeTheDot, theExpressionAfterTheDot)
。如果没有圆点,则表示我们在列表中,其后是尾巴。所以我们要返回
Cons(theExpression, parseRest())
。
nextToken()
时将返回哪个令牌,而无需实际更改对
nextToken()
的下一次调用将返回的内容。因此,您将拥有另一个内置函数,例如
peekNext()
,它可以返回下一个令牌,而无需实际推进令牌流中的迭代器。
peekToken
而不是
nextToken
(不过,当它是点时,仍需要删除令牌)。
关于java - 为我愚蠢:解析是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25836072/
不能制造愚蠢。具有下一个文件夹结构: /flint/double-conversion/src /燧石/愚蠢/愚蠢/ 其中/flint/folly 包含自述文件和许可证。作为in the readme
我有一个小问题,它可能在某个地方很愚蠢,但我仍然有它:) 所以问题是: 通过这样做 round(615.36*0.10, 2, PHP_ROUND_HALF_DOWN); 我希望结果是 61.53,但
我正在寻找一个只是为了大致了解应该如何正确设置标准 C++ 项目。(如果可能的话……:-p) 这是我对这个项目的要求: 基于模块(具有编译成主程序模块的库/模块) 编译跨平台 我想这样做,这样我就可以
我是一名优秀的程序员,十分优秀!