我正在制作词法分析器和解析器来将一种数据格式解析为另一种(部分作为练习),我有一个问题:
假设我们有3种不同的数据类型,这些数据类型由分隔符标识:
a | b#我们称之为“段”
a~b#我们称之为“数组”
a ^ b#我们称之为“组件”
你也可以像这样混合它们:
hey~there|how~are~you
这对应于伪代码中的类似内容:
[["hey", "there"], ["how", "are", you"]]
和
hey~there^you~guy|hi|hehe
对应于:
[[["hey", "there"], ["you", "guy"]], "hi", "hehe"]
现在我的问题是,在我的词法分析器中,我展望未来,看看我们正在处理什么类型的数据,这样我才能在所有字符串和分隔符被发出之前首先发出令牌类型?或者我是否让解析器尝试通过它获得的分隔符来计算出来?
hey~there^you~guy|hi|hehe
的示例:
(segment)
(component)
(array)
(string "hey")
(array_delim "~")
(string "there")
(component_delim "^")
(component)
(array)
(string "you")
(array_delim "~")
(string "guy")
(segment_delim "|")
(string "hi")
(segment_delim "|")
(string "hehe")
与
(string "hey")
(array_delim "~")
(string "there")
(component_delim "^")
(string "you")
(array_delim "~")
(string "guy")
(segment_delim "|")
(string "hi")
(segment_delim "|")
(string "hehe")
在第一种情况下,解析器会知道组件或数组即将到来,并提前制作正确的数据结构。在第二个例子中,它有点必须回溯它所做的事情,因为它确定了它后来的数据结构。
答案 0 :(得分:1)
我相信第二个例子就是你想要使用的。从它的外观来看,您的语法具有以下优先级。
segments = 0
components = 1
array = 2
考虑到这一点,您可以实施Operator-precedence parser。哪个会像这样处理您的令牌:
shift (string "hey")
shift (array_delim "~")
shift (string "there")
reduce array1
shift array1
shift (component_delim "^")
shift (string "you")
shift (array_delim "~")
shift (string "guy")
reduce array2
reduce component1
shift component1
shift (segment_delim "|")
shift (string "hi")
reduce segment1
shift segment1
shift (segment_delim "|")
shift (string "hehe")
reduce segment2
done
这将导致像这样的解析树。
segment
segment
component
array
string(hey)
string(there)
array
string(you)
string(guy)
string(hi)
string(hehe)