Compiler construction 使用语法定向转换方案将整数转换为罗马数字?

Compiler construction 使用语法定向转换方案将整数转换为罗马数字?,compiler-construction,roman-numerals,translation-scheme,Compiler Construction,Roman Numerals,Translation Scheme,龙书包括一个使用语法导向翻译方案将整数转换为罗马数字的练习 这是怎么完成的? 我会考虑从右向左解析。 首先,我将映射“单位”列: 0 -> '' 1 -> 'I' 2 -> 'II' 3 -> 'III' 4 -> 'IV' ... 9 -> 'IX' 然后,如果有第二列(例如,右起第二列=十列),我将使用该列映射到 0 -> '' 1 -> 'X' 2 -> 'XX' ... 9 -> 'XC' 这将需要在初始输出之前加上前缀 对

龙书包括一个使用语法导向翻译方案将整数转换为罗马数字的练习


<>这是怎么完成的?

我会考虑从右向左解析。

首先,我将映射“单位”列:

0 -> ''
1 -> 'I'
2 -> 'II'
3 -> 'III'
4 -> 'IV'
...
9 -> 'IX'
然后,如果有第二列(例如,右起第二列=十列),我将使用该列映射到

0 -> ''
1 -> 'X'
2 -> 'XX'
...
9 -> 'XC'
这将需要在初始输出之前加上前缀

对下一列(成百上千)重复此操作,直到字母用完为止


再次检查数字是否为“0”或负数。

另一种方法是将罗马数字存储在二维数组中,以表示1、5、10、50、100、500、1000等。示例(在PHP数组中):

然后从右到左取每个数字,并应用以下翻译。设置变量$level=0,并在处理每个数字后将其值增加1:

1 => $roman[$level][1]
2 => $roman[$level][1].$roman[$level][1]
3 => $roman[$level][1].$roman[$level][1].$roman[$level][1]
4 => $roman[$level][1].$roman[$level][5]
5 => $roman[$level][5]
6 => $roman[$level][5].$roman[$level][1]
7 => $roman[$level][5].$roman[$level][1].$roman[$level][1]
8 => $roman[$level][5].$roman[$level][1].$roman[$level][1].$roman[$level][1]
9 => $roman[$level][1].$roman[$level][10]
(在PHP中,“.”表示两个字符串)

例子:1945年

5 => $roman[0][5] = "V"
4 => $roman[1][1].$roman[1][5] = "XL"
9 => $roman[2][1].$roman[2][10] = "CM"
1 => $roman[3][1] = "M"
所以翻译后的数字是“MCMXLV”


很抱歉,这可能无法完全回答您的问题,但我希望它在任何方面都有所帮助。

接下来是语法,用于表示从1xx格式的数字到罗马数字的语法转换

数字=一个数字和一个数字3个数字2个数字1 | nzdigit3个数字2个数字1 | nzdigit2个数字1 | nzdigit1

1小时->1{print('M')}

数字3->0数字3->nzdigit3

nzdigit3->1打印('C')nzdigit3->2打印('CC')nzdigit3->3 打印('CCC')nzdigit3->4打印('CCCC')nzdigit3->5打印('D')) nzdigit3->6打印('DC')nzdigit3->7打印('DCC')nzdigit3->8 打印('DCCC')nzdigit3->9打印('DCCC'))


以类似的方式为2和1位置的数字写下定义,您将需要翻译。

看起来像家庭作业问题,闻起来像家庭作业问题…;-)是的,我知道。。。我希望我能证明我没有作弊。这实际上是一个家庭作业问题,对于CS学生来说。。。只是,不是对我来说,我只是一个人在读这本书,没有老师(或有足够知识的朋友)去问。这意味着,制作一个上下文无关的语法,然后允许我使用sytanx指导的翻译方案进行转换,我需要为每个“列”创建10条规则。(所以,大约34条规则才能到达3999)我说的对吗?我实际上想到了类似的事情,我有点期待有一个更优雅的方法。。。有吗?是的,这意味着每栏有10条规则。我想你可以为每一列编写一个函数,并将字母作为参数。。。因此,对于219,您将输出f(2,'C','D','M')+f(1,'X','L','C')+f(9,'I','V','X')并没有感觉到上下文无关。这是错误的答案,因为这里没有语法。必须不存在任何功能。转换必须在树遍历过程中给出结果,并且不能确定您在树中的深度。
5 => $roman[0][5] = "V"
4 => $roman[1][1].$roman[1][5] = "XL"
9 => $roman[2][1].$roman[2][10] = "CM"
1 => $roman[3][1] = "M"