如果我的语言包含基本的内容,例如
a = expression
if expression then ...
while expression do ...
然后我可能会有一个如下所示的语法:(伪代码)
assignment: identifier Equals expression ;
if : If expression Then ...
while : While expression Do ...
现在,第一个表达式的类型只需要与' a'但是其他两个表达式必须是boolean类型。
虽然在任何地方检查表达式的类型都很容易,但在我看来,在语法中定义是非常方便的
boolExpression : expression;
然后我的其他规则看起来像这样:
assignment: identifier Equals expression ;
if : If boolExpression Then ...
while : While boolExpression Do ...
这将允许我检查boolExpression返回BOOL类型,因此我不必添加代码来测试每个表达式。
但是,我是否通过这样做将上下文无关语法转换为上下文敏感语法?如果是这样,那有关系吗?
答案 0 :(得分:2)
如果您有布尔变量,那么您无法在语法上验证表达式是否为布尔值。如果要捕获所有类型检查,则需要某种语义反馈,这确实会使语言对上下文敏感,并且除非您需要变量,否则也无法进行从左到右的解析。在使用前声明。 [见注1]这种形式的语义反馈通常被认为是一个复杂因素,因为它在词法分析和解析之间产生紧密耦合,但许多解析器都是为了方便或必要而这样做。
但也许你只满足于只检测某些情境。如果是这样,你的语法肯定是可行的,并不会创建上下文敏感性。 if
和while
语句肯定提供了语法决定的布尔上下文。算术运算符提供了一个确定的数字上下文(尽管如果你有多种算术类型,你可能需要进行类型检查。)但是有些语法在语法上不是类型决定的,例如赋值语句,相等运算符和函数调用。因此,您最终将在散步的各个地方进行特殊情况类型检查。
就个人而言,我没有看到试图使语法复杂化以尝试进行部分类型检查的优势;我更喜欢在解析后进行类型验证/扣除传递。但在某些用例中,灵活性较低的方法是完全合理的。
有些语言在使用前声明非常坚定(例如C),但是其他语言允许程序员逻辑地命令变量声明,而不必担心对它们的引用(例如,C ++类声明)。 / p>
就个人而言,我宁愿在使用前坚持声明,也不会使程序员的生活复杂化。实际上,作为程序员,我欣赏能够推导变量类型而不是坚持冗余声明的语言。但味道不同。无论如何,强制声明并不一定意味着在使用前声明,并且许多具有强制声明的语言仍然提供关于声明顺序的灵活性,允许(例如)相互递归的函数而没有多余的前向声明。
答案 1 :(得分:1)
不,这些更改不会将您的无上下文语法转换为上下文相关语法。
你可以通过观察作品的左侧来区分:只要每个LHS是一个单一的符号,它就是一个CFG。如果任何LHS有多个符号,那么它就是CSG。
(这有点过于简单化,但它足以准确回答你的问题。)
那些语法,但是当谈到 languages 时,请注意您的语法生成的语言与类型有效程序的语言不同。前者没有上下文,但后者可能不是。