【问题标题】:Good parsing approach after tokenization [closed]标记化后的良好解析方法[关闭]
【发布时间】:2017-04-24 03:07:38
【问题描述】:

我编写了一个程序,在其中读取字符串或文件并对其进行标记。 示例字符串: "int w = sad&&s||a|d++ != == < > >= <= -- sadsa++ % int sads = 232.32; if reg string test = \"Hello World\";% % +- + - / * ** false true"

示例输出:

Token[Type:'Identifier',Value:'int',Line:'1',Position:'3']
Token[Type:'Literal',Value:'w',Line:'1',Position:'4']
Token[Type:'Assign',Value:'=',Line:'1',Position:'4']
Token[Type:'Literal',Value:'sad',Line:'1',Position:'8']
Token[Type:'Logical',Value:'&&',Line:'1',Position:'8']
Token[Type:'Literal',Value:'s',Line:'1',Position:'11']
Token[Type:'Logical',Value:'||',Line:'1',Position:'11']
Token[Type:'Literal',Value:'a',Line:'1',Position:'14']
Token[Type:'Unknown',Value:'|d',Line:'1',Position:'14']
Token[Type:'Literal',Value:'d',Line:'1',Position:'16']
Token[Type:'Arithmetic',Value:'++',Line:'1',Position:'16']
Token[Type:'Relational',Value:'!=',Line:'1',Position:'18']
Token[Type:'Relational',Value:'==',Line:'1',Position:'20']
Token[Type:'Relational',Value:'<',Line:'1',Position:'22']
Token[Type:'Relational',Value:'>',Line:'1',Position:'23']
Token[Type:'Relational',Value:'>=',Line:'1',Position:'24']
Token[Type:'Relational',Value:'<=',Line:'1',Position:'26']
Token[Type:'Arithmetic',Value:'--',Line:'1',Position:'28']
Token[Type:'Literal',Value:'sadsa',Line:'1',Position:'35']
Token[Type:'Arithmetic',Value:'++',Line:'1',Position:'35']
Token[Type:'Arithmetic',Value:'%',Line:'1',Position:'37']
Token[Type:'Identifier',Value:'int',Line:'1',Position:'41']
Token[Type:'Literal',Value:'sads',Line:'1',Position:'45']
Token[Type:'Assign',Value:'=',Line:'1',Position:'45']
Token[Type:'DoubleValue',Value:'232.32',Line:'1',Position:'51']
Token[Type:'Semicolon',Value:';',Line:'1',Position:'51']
Token[Type:'Identifier',Value:'if',Line:'1',Position:'53']
Token[Type:'Literal',Value:'reg',Line:'1',Position:'56']
Token[Type:'Identifier',Value:'string',Line:'1',Position:'62']
Token[Type:'Literal',Value:'test',Line:'1',Position:'66']
Token[Type:'Assign',Value:'=',Line:'1',Position:'66']
Token[Type:'StringValue',Value:'Hello World',Line:'1',Position:'78']
Token[Type:'Semicolon',Value:';',Line:'1',Position:'78']
Token[Type:'Arithmetic',Value:'%',Line:'1',Position:'78']
Token[Type:'Arithmetic',Value:'%',Line:'1',Position:'79']
Token[Type:'Unknown',Value:'+-',Line:'1',Position:'80']
Token[Type:'Arithmetic',Value:'+',Line:'1',Position:'82']
Token[Type:'Arithmetic',Value:'-',Line:'1',Position:'83']
Token[Type:'Arithmetic',Value:'/',Line:'1',Position:'84']
Token[Type:'Arithmetic',Value:'*',Line:'1',Position:'85']
Token[Type:'Unknown',Value:'**',Line:'1',Position:'86']
Token[Type:'Identifier',Value:'false',Line:'1',Position:'93']
Token[Type:'Identifier',Value:'true',Line:'1',Position:'97']
Elapsed time: 31

(忽略位置,以后要修复)

所以现在我真的不知道有什么好的方法来进一步解释这个以便我自己运行一个简单的小脚本语言。

【问题讨论】:

    标签: c# parsing token interpreter


    【解决方案1】:

    一个好的第一种方法是为每件事想出名称,例如“操作”、“操作数”、“文字”、“声明”等。

    然后创建一个函数,该函数可以从您的令牌流中读取其中的每一个,并在适当的时候调用其他的。例如。如果你有:

    operation: <operand> <operator> <operand>
    operator: + | -
    operand: <number> | <string>
    

    等等,那么你就可以有一个函数(伪代码):

    Operation parseOperation( tokens )
    {
        Operand operand1 = parseOperand( tokens )
        Operation theOp = new Operation( tokens.fetchNextToken() )
        Operand operand2 = parseOperand( tokens )
        theOp.operand[0] = operand1
        theOp.operand[1] = operand2
        return theOp
    }
    

    并以类似的方式实现其他功能。当然,有些函数可能需要检查下一个标记来决定调用哪个其他函数,甚至可以提前几个标记。

    这通常称为“递归下降”解析器。

    每个函数都返回一个对象,该对象代表一个操作,并有它的参数挂在它上面。这基本上是一个树结构,然后您可以递归地遍历它(“深度优先”)。

    最简单的方法是给你定义的不同对象类型或你的操作和值方法,如 asString() 或 asInt(),然后执行以下操作:

    int Operation::asInt()
    {
       int a = operand[0].asInt()
       int b = operand[1].asInt()
       return a + b;
    }
    

    已经是正确类型的对象(如 IntOperand 类)只会返回它们的值:

    int IntOperand::asInt()
    {
        return self.numericValue
    }
    

    或其他。不正确类型的对象要么产生错误而不是返回值,要么自行转换。所以无论表达式多么复杂,最后你都会得到一个 int 或 string 或任何输出。

    要运行程序,您现在可以向最底部的对象询问其值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多