0

这几天我一直对此感到困惑,搜索似乎没有给出任何结果。让我想知道这是否可能。例如:

funct functionNAME (Object o) { o+1 };

关键是用户必须在花括号内使用标识符“o”,而不是其他标识符。这当然是由 (Object o) 部分中的输入指定的,其中 'o' 可以是任何东西。基本上花括号内的标识符必须与参数中定义的标识符相同。我知道我可以存储匹配的标记并将其打印到屏幕上,但是否可以将其用作词法标记本身?谢谢。

4

3 回答 3

2

是的,有更好的方法来做到这一点。你需要一个符号表。符号表的工作是跟踪程序中每个点可以使用哪些标识符。通常,符号表还包含有关标识符的其他信息,例如它们表示的内容(例如变量或函数名称)以及它们的类型。

使用符号表,您可以检测在解析许多语言(但不是全部)期间不在范围内的变量的使用。例如,C 和 Pascal 是必须在使用标识符之前声明标识符的语言(有一些例外)。但是其他语言(例如Java)允许在使用标识符之后声明标识符,在这种情况下,最好不要尝试检测错误,例如在程序被解析之前使用未声明的变量。(实际上,在 Java 中,您需要等到所有文件都被解析,因为标识符可能会在另一个文件中声明。)

我假设一个简单的场景,就是你只需要记录变量的信息,没有类型信息,使用前必须声明。这会让你开始。我没有为将函数名添加到符号表而烦恼。

假设一个符号表是一堆叫做帧的东西。每个帧都是一组可变的字符串。(稍后您可能希望将其更改为从字符串到一些附加信息的可变映射。)

void Start(): { }
{
    <FUNCTION>
    <IDENTIFIER>
    {symttab.pushNewFrame() ;}
    <LBRACKET> Parameters()  <RBRACKET> 
    <LBRACE> Expression() <RBRACE>
    {symtab.popFrame() ; }
}
void Parameters() : {}
{
     ( Parameter() (<COMMA>   Parameter() )* )?
}
void Parameter() : {  Token x ; }
    <OBJECT> x=<IDENTIFIER>
    { if( symtab.topFrame().contains(x.image) ) reportError( ... ) ; }
    { symtab.topFrame().add(x.image) ; }
}
void Expression() : {  }
{
    Exp1() ( <PLUS> Exp1() )*
}
void Exp1() : { Token y ; }
{
    y = <IDENTIFIER>
    { if( ! symtab.topFrame().contains(y.image) ) reportError( ... ) ; }
|
    <NUMBER>
}
于 2013-04-01T19:13:22.213 回答
0

您可以存储标识符 matchin 的值o,然后在大括号中检查标识符是否相同,否则抛出异常。

于 2013-03-28T17:11:06.817 回答
0

好的,我已经根据我在 OP 中给出的示例找到了一种方法来获得我想要的东西。这是我在我的解决方案中实现的一个简单变体,只是为了提供概念证明。为简单起见,将省略诸如令牌定义之类的琐碎事情。

void Start():
{
    Token x, y;
}
{
    <FUNCTION>
    <FUNCTION_NAME>
    <LBRACKET>
    <OBJECT>
    x = <PARAMETER>
    <RBRACKET>
    <LBRACE>
    y = <PARAMETER>
    {
        if (x.image.equals(y.image) == false)
        {
            System.out.println("Identifier must be specified in the parameters.");
            System.exit(0);
        }
    }
    <PLUS>
    <DIGIT>
    <RBRACE>
    <COLON>
}

有一个更好的方法吗?

于 2013-03-31T15:56:10.240 回答