一个新程序员应该如何理解“解析”这个概念?

89

我是一名计算机科学专业的大学生。我的很多同学并没有真正做过太多编程。他们完成了课堂作业,但说实话那些问题并不能真正教你如何编程。

我曾经有几个同学问我如何解析某些内容,但我从来不确定该如何向他们解释。是一行一行地寻找子字符串最好呢,还是给他们更复杂的讲解,例如使用正确的词法分析等创建令牌,使用BNF等所有其他东西?当我试图解释时,他们从未完全理解。

在不让他们困惑或泄气的情况下,最好的方法是什么。


5
我曾购买的最好的书之一是Ronald Mak的《编写编译器和解释器》。虽然我从未真正编写过一个完整的编译器,但它是将复杂问题分解为可管理的部分的绝佳示例。不过对于大多数人来说可能有点过度了。 - Daniel Pratt
@Daniel Pratt - +1。那是一本很棒的书,通过阅读我学到了很多东西。 - user113476
解析是编译过程中的语法分析部分。它仅确定指定的输入是否有效。您的问题是否与此有关?还是关于更广泛的语言解释主题? - CARLOS LOTH
8个回答

96

我认为解析是将某种数据转换为另一种数据的过程。

在实践中,这对我来说几乎总是将字符串或二进制数据转换为程序内的数据结构。

例如,将

":Nick!User@Host PRIVMSG #channel :Hello!"

C语言中的into。

struct irc_line {
    char *nick;
    char *user;
    char *host;
    char *command;
    char **arguments;
    char *message;
} sample = { "Nick", "User", "Host", "PRIVMSG", { "#channel" }, "Hello!" }

6
卡洛斯是正确的。解析并不会将数据转化为其他任何东西。解析只是对一系列字符(或标记)进行分析。从分析中创建出某个东西则完全是另一回事。 - jpbochi
5
在某个存在层面上,每个程序都是关于将一种数据转换成另一种数据的(这不就是函数的定义吗?)。我认为更清晰地表达它的方式是说解析是将输入的位分配名称的过程。在你的例子中,你将名称sample.message分配给字符“Hello!”。这是将名称分配给意义的任务的必要前提,但完全独立于分配名称的任务 - 例如,sample.message表示什么或者做什么?正如Carlos所指出的那样,那就变成了语义分析 - Daniel Pryden

52

语法分析是指对由一系列标记组成的文本进行分析,以确定其与给定(或多或少)正式的语法结构相匹配。

解析器会根据标记构建数据结构。然后编译器、解释器或翻译器可以使用这个数据结构来创建可执行程序或库。

alt text
(来源: wikimedia.org)

如果我给你一句英文句子,并要求你将该句子分解为其各部分的词性(名词、动词等),那么你就在进行解析。

这是我能想到的最简单的解析概述。

话虽如此,解析是一个非常复杂的计算问题。你需要从简单的例子开始,逐步提高难度。


42

什么是解析?

在计算机科学中,解析是指分析文本以确定它是否属于特定的语言(即是否符合该语言的语法)的过程。这是句法分析过程的非正式名称。

例如,假设语言a^n b^n(表示相同数量的字符A后跟相同数量的字符B)。 该语言的解析器将接受AABB输入并拒绝AAAB输入。这就是解析器的作用。

此外,在此过程中,可以创建数据结构以进行进一步处理。在我的前面的例子中,它可以将AABB分别存储在两个单独的堆栈中。

任何之后发生的事情,比如赋予AABB意义,或者将其转换为其他内容,都不是解析。赋予令牌序列输入部分含义称为语义分析

什么不是解析?

  • 解析不是将一件事物转化为另一件事物。 将A转化为B,本质上就是编译器所做的。编译需要多个步骤,解析只是其中之一。
  • 解析不是从文本中提取含义。 这是编译过程中的语义分析步骤。

最简单的理解方式是什么?

我认为理解解析概念的最好方法是从简单的概念开始。在语言处理学科中最简单的概念是有限自动机。它是用于解析正则语言(如正则表达式)的形式化工具。

它非常简单,你有一个输入、一组状态和一组转换。考虑以下由字母表 { A, B } 构建的语言,L = { w | w以'AA'或'BB'作为子字符串开始 }。下面的自动机表示该语言的一个可能的解析器,其所有有效单词都以'AA'或'BB'开头。

    A-->(q1)--A-->(qf)
   /  
 (q0)    
   \          
    B-->(q2)--B-->(qf)

这是一种非常简单的语言解析器。你从初始状态(q0)开始,然后从输入中读取一个符号,如果它是A,那么你就移动到(q1)状态,否则(它是B,请记住字母表只有AB)你就移动到(q2)状态,以此类推。如果你到达了(qf)状态,那么输入就被接受了。
由于这种方式很直观,所以你只需要一支铅笔和一张纸就可以向任何人,包括孩子,解释什么是解析器。我认为简单性是自动机最适合教授语言处理概念,例如解析的原因。
最后,作为计算机科学专业的学生,你将在理论计算机科学课程,如形式语言和计算理论中深入学习这些概念。

5

让他们尝试编写一个能够评估任意简单算术表达式的程序。这是一个简单易懂的问题,但随着进一步深入研究,很多基本的解析开始变得有意义。


4
解析是指读取一种格式的数据,以便你可以将其用于自己的需求。我们通常尝试逐行解析数据,因为这样人类更容易思考,分而治之,编码也更容易。我们称每个最小不可分割数据为字段。例如,姓名是一个字段,年龄是另一个字段,姓氏是另一个字段。在一行中,我们可以有各种字段。为了区分它们,我们可以通过分隔符或分配给每个字段的最大长度来对字段进行分隔。任何前面的字段集都被称为记录。要在分隔字段记录之间进行分隔,我们需要分隔记录。一个点就足够了(虽然你知道你可以应用CR / LF)。你可以让他们列出他们喜欢的10个NBA(或NLF)球员。然后,他们应该按照格式输入它们。然后制作一个程序来解析它并显示每个记录。一个团队可以制作以逗号分隔格式列出列表和解析固定大小格式列表的程序,反之亦然。

2
-1 将数据从一种格式转换为另一种格式是编译。 - CARLOS LOTH
2
我的回答旨在为初学者提供实用的帮助,以便他们更轻松地学习。随后,他们可以处理更多方面,如语法分析、解析、语法等等... - user347594
2
解析并不是转换任何东西。解析只是读取。滥用概念将会导致更多的混淆。 - jpbochi

2

在语言学中,将语言分成可以分析的小组件。例如,解析这个句子就需要将其分成单词和短语,并确定每个组件的类型(例如动词、形容词或名词)。

解析是许多计算机科学学科中非常重要的一部分。例如,编译器必须解析源代码才能将其转换为目标代码。同样,任何处理复杂命令的应用程序都必须能够解析命令。这包括几乎所有终端用户应用程序。

解析通常分为词法分析和语义解析两部分。词法分析集中于基于标点符号和其他关键字将字符串分成组件,称为标记。然后语义解析试图确定字符串的含义。

http://www.webopedia.com/TERM/P/parse.html


2
解析对我来说是将某物分解为有意义的部分...使用可定义或预定义的已知、常见的部分“定义”。
对于编程语言,可能会有关键字部分、可用的标点符号序列...
对于南瓜派来说,可能是酥皮、馅料和配料。
对于书面语言,可能会有一个单词是什么,一个句子是什么,动词是什么...
对于口语语言,可能是语调、音量、情绪、暗示、情感、上下文
语法分析(以及常识)会告诉你正在解析的是南瓜派还是编程语言。它有酥皮吗?嗯,也许是南瓜布丁,或者是口语语言!
需要注意的一件事是,解析东西通常有很多方法可以将其分解成部分。
例如,你可以通过从中心到边缘切开南瓜派,从下到上切开南瓜派,用勺子取出馅料,用铁锤砸开或食用。
如何解析这些东西将决定使用这些部分做一些事情是容易还是困难。
在“计算机语言”世界中,有常见的方法来解析文本源代码。这些常见的方法(算法)有标题或名称。在互联网上搜索解析语言的常见方法/名称。维基百科可以帮助你在这方面。

1
简单解释:解析是按照一组规则(例如使用分隔符)将数据块分解为较小的片段(标记),以便可以逐个处理此数据(管理、分析、解释、传输等)。
例子:许多应用程序(如电子表格程序)使用CSV(逗号分隔值)文件格式导入和导出数据。CSV格式使应用程序能够借助特殊解析器处理此数据。 Web浏览器具有用于HTML和CSS文件的特殊解析器。JSON解析器存在。所有特殊文件格式都必须有专门为它们设计的某些解析器。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接