【问题标题】:Tokenizing a string that could be a tuple or something else标记一个可能是元组或其他东西的字符串
【发布时间】:2020-04-11 01:29:57
【问题描述】:

我正在为基本编程语言构建词法分析器(标记器)和解析器,我正在考虑的语言功能之一是将字符串解析为元组或表达式的选项。问题是我被困在如何从字符串中确定它是否应该是元组。起初,我以为我可以检查字符串是否以 '(' 开头并以 ')' 结尾以及在内部某处包含 ',',但这种方法的问题是表达式也可以包含元组。

是否有规范或公认的方法来判断字符串是否为元组?

【问题讨论】:

    标签: regex parsing split tokenize lexer


    【解决方案1】:

    词法分析器无法确定 ( 是否是元组的一部分。它只识别(。这就是它所要做的。

    解析器的工作是确定特定符号的含义。解析器将使用语言的语法描述来区分元组、带括号的表达式、参数列表以及括号的所有其他可能含义。

    当然,精确的语法取决于语言的语法,但一个简单的例子可能是:(大致改编自 Python,但缺少很多语法)

    expr  : term             /* Additive operators, lowest precedence */
          | expr '+' term
          | expr '-' term
    term  : factor           /* Multiplicative operators */
          | term '*' factor
          | term '/' factor
    factor: postfix          /* Unary prefix operators */
          | '-' factor
          | '+' factor
    post  : unit             /* Postfix operators: call and subscript */
          | post '(' opt_expr_list ')'
          | postfix '[' expr ']'
    unit  : CONSTANT         /* Values */
          | IDENTIFIER
          | tuple
          | '(' expr ')'     /* Parenthesised expression */
    tuple : '(' ')'          /* Empty tuple */
          | '(' expr ',' ')' /* Single-element tuple eg. (1, ) */
          | '(' expr ',' expr_list opt_comma ')'
                             /* Two or more elements */
    opt_comma
          : %empty
          | ','
    expr_list
          : expr
          | expr_list ',' expr
    opt_expr_list
          : %empty
          | expr_list
    

    请注意,语法经过精心设计,可以将元组与带括号的表达式区分开来。使用的约定是元组可以在最后一个元素之后写上,,除非元组只有一个元素,在这种情况下逗号是强制性的。这稍微需要将元组的语法分成三个产生式,但并不特别复杂。

    还请注意,在描述函数调用的语法时,没有必要跳过这个特定的环节。不可能将sin(3) 中的(3) 与带括号的表达式混淆,因为带括号的表达式(与其他值一样)不能立即跟在没有某种运算符的表达式之后。

    【讨论】:

    • 抱歉,我应该澄清一下我同时在处理词法分析器/解析器。我对术语感到困惑,但我的问题仍然存在:解析器是如何做到这一点的?
    • @david:这取决于语言的语法。你看过一些语法吗? Python,也许吧?
    • 我添加了一个示例语法。这是一个 LALR(1) 语法,bison(或其他类似的解析器生成器)将能够从中生成解析器。这不是 LL(1)。您可以在 Python 文档中看到类似 LL(1) 语法的内容,但它更加混乱,老实说,我认为以这种方式限制自己没有任何意义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-28
    • 1970-01-01
    • 1970-01-01
    • 2015-10-05
    • 1970-01-01
    • 2018-01-15
    • 2016-02-02
    相关资源
    最近更新 更多