笔记-编译原理-第七、八、九章-语法分析-自上而下分析

第七章-自上而下分析1

7.1 自上而下分析的基本问题

7.1.1语法分析的前提

对语言的语法结构进行描述
  • 采用 正规式有限自动机 描述和识别语言的 单词符号
  • 上下文无关文法 来描述语法规则

上下文无关文法即第二章的内容:上下文无关文法

语法分析的任务
  • 语法分析的任务 :分析一个文法的句子的结构
  • 语法分析器的功能 :按照文法的产生式(语言的语法规则),识别输入符号 串是否为一个句子(合式程序)

7.1.2语法分析器在编译器中的地位

语法分析的过程:语法分析的过程

7.1.3语法分析的方法

语法分析的方法有两种:自上而下 以及 自下而上 :

自下而上(Bottom-up)自上而下(Top-down)
从输入串开始,逐步进行归约,直到文法的开始符号从文法的开始符号出发, 反复使用各种产生式,寻 找"匹配"的推导
归约:根据文法的产生式规则,把串中出现的产生 式的右部替换成左部符号推导:根据文法的产生式 规则,把串中出现的产生 式的左部符号替换成右部
从树叶节点开始,构造语法树从树的根开始,构造语法树
算符优先分析法、LR分析法递归下降分析法、预测分析程序

7.1.4 自上而下分析面临的问题

自上而下分析的过程

基本思想:

  • 从文法的开始符号出发,向下推导,推出句子
  • 针对输入串,试图用一切可能的办法,从文法开始 符号(根结点)出发,自上而下地为输入串建立一棵语法树

一个例子:自上而下分析的一个例子
从上面的例子可以看出:

多个产生式候选带来的问题
  • 回溯问题:分析过程中,当一个非终结符用某一个候选匹配成 功时,这种匹配可能是暂时的,出错时,不得不“回溯”(一个dfs的过程)
  • 文法左递归问题:可能某个终结符可以不断的使用自身来扩展下去,这样在语法树中就是一个不断左递归的过程,一个文法是含有左递归的,如果存在非终结符 P : P → P a P:P \to Pa P:PPa ,这样的,会导致死循环:文法的左递归问题

7.2 LL(1)文法——消除文法的左递归

因为直接自上而下分析会有 回溯左递归 问题,所以要先进行 消除文法的左递归性 以及 消除回溯 ,以 构造不带回溯的自上而下分析算法

7.2.1 直接左递归的消除

(看图吧,md排版不怎么好。。。)
左递归变右递归
左递归变右递归的一般表达式
例如这样的一个文法的消除例子:

7.2.2 间接左递归的消除

一个文法消除左递归的条件 :

  • 不含以ε为右部的产生式
  • 不含回路,就是不会出现一个非终结符推着推着出现了自己开头的

例如对这样一个文法S的间接左递归的消除:
左递归消除

这个过程就是不断的用下层的替换前面出现的,这样一直替换下去最后第一层就只有一个非终结符组成的文法了,最后有直接左递归的就用上一个方法去掉就行了。

这个间接左递归的具体消除算法如下:
左递归消除算法

对于上面的那个例子的消除结果就是:

{ S → a b c S ′ ∣ b c S ′ ∣ c S ′ S ′ → a b c S ′ ∣ ε \begin{cases} S → abcS'| bcS'| cS' \\ S'→ abcS'| ε \end{cases} {SabcSbcScSSabcSε

  • 注意,由于对非终结符排序的不同,后所得的文法在形式上可能不一样。但不难证明,它们都是等价的。

7.3 LL(1)文法——消除回溯

7.3.1 消除回溯的目的

为了消除回溯必须保证:对文法的任何非终结符,当要它去匹配输入串时, 能够根据它所面临的输入符号 准确地 指派它的一个候选去执行任务,并且此候选的工作结果应是确信无疑的(将多种可能的搜索变成单一的匹配)。

7.3.2 FIRST集合

令G是一个不含左递归的文法,对G的所有 非终结符 的每个候选α定义它的终结首符集FIRST(α) 为:

F I R S T ( α ) = { a ∣ α ⇒ ∗ a . . . , a ∈ V T } 特 别 的 , 若 α ⇒ ∗ ε , 则 规 定 ε ∈ F I R S T ( α ) FIRST(\alpha)=\{a|\alpha⇒^*a..., a \in V_T\} \\ 特别的,若 \alpha ⇒^* ε,则规定 ε \in FIRST(\alpha) FIRST(α)={aαa...,aVT}αεεFIRST(α)

就是某个非终结符 α \alpha α 其所有的可能推导出的句子的首字符组成的集合。

如果非终结符A的所有候选首符集两两不相交, 即A的任何两个不同候选 α i α_i αi α j α_j αj F I R S T ( α i ) ∩ F I R S T ( α j ) = φ FIRST(α_i)∩FIRST(α_j)=φ FIRST(αi)FIRST(αj)φ , 当要求A匹配输入串时,A能根据它所面临的 第一个输入符号a,准确地指派某一个候选去执行任务。这个候选就是那个终结首符集含a的α。 (也就说,只要我们可以使得A下的产生式的First集合两两不相交,这样就可以唯一确定一个字符出现在那个First集合中,这样就可以从该产生式扩展下去,也就达到了消除回溯的目的:示例

而达到这一目的(两两不相交)的方法就是 提取公共左因子

7.3.3 提取公共左因子(通过大量引入非终结符的方法)

提取公共左因子

7.3.4 ε ε ε候选

这样的一个例子:一个分析的例子

在进行分析的过程中,对 T‘的推导中使用了 ε ε ε ,这里选用的原因之一就是 T’包含这样的一个句型,所以才使用 ε ε ε 来跳过:空字问题

7.3.5 FOLLOW集合

假定S是文法G的开始符号,对于G的任何非终结符A,我们定义A的FOLLOW集合:

F O L L O W ( A ) = { a ∣ S ⇒ ∗ . . . A a . . . , a ∈ V T } 特 别 是 , 若 S ⇒ ∗ . . . A , 则 规 定 # ∈ F O L L O W ( A ) FOLLOW(A)=\{a|S ⇒^* ...Aa..., a \in V_T\} \\ 特别是,若 S ⇒^* ...A, 则规定 \# \in FOLLOW(A) FOLLOW(A)={aS...Aa...,aVT}S...A,#FOLLOW(A)

(也就是指FOLLOW(A) 为所有可能跟在非终结符A后的终结符的集合)
解释

7.3.6 构造不带回溯的自上而下分析的文法条件

  • 文法不含左递归
  • 对于文法中每一个非终结符A的各个产生式的候选首符集两两不相交。即,若 A → α 1 ∣ α 2 ∣ … ∣ α n A→α_1|α_2|…|α_n Aα1α2αn ,则 F I R S T ( α i ) ∩ F I R S T ( α j ) = φ ( i ≠ j ) FIRST(α_i)∩FIRST(α_j)=φ(i≠j) FIRST(αi)FIRST(αj)φ(i=j) (保证了不回溯)
  • 对文法中的每个非终结符A,若它存在某个候选首符集包含ε,则 F I R S T ( α i ) ∩ F O L L O W ( A ) = φ , i = 1 , 2 , . . . , n FIRST(α_i)∩FOLLOW(A)=φ,i=1,2,...,n FIRST(αi)FOLLOW(A)=φi=1,2,...,n (保证在选取ε时仅选择的是唯一一个产生式)

如果一个文法G满足以上条件,则称该文法G为LL(1)文法。 其中:

  • 第一个L: 从左到右扫描输入串
  • 第二个L: 最左推导
  • 1: 每一步只需向前查看一个符号

7.3.6 LL(1)分析法

对于经过处理后的满足上述条件的LL(1)文法,可以对其输入串进行 有效的 无回溯的 自上而下分析

  • 假设要用非终结符A进行匹配,面临的 输入符号为a,A 的所有产生式为 A → α 1 ∣ α 2 ∣ … ∣ α n A→α_1 | α_2 | … | α_n Aα1α2αn
  • 1.若 a ∈ F I R S T ( α i ) a∈FIRST(α_i) aFIRST(αi) ,则指派 α i α_i αi 执行匹配任务;
  • 2.若a不属于任何一个候选首符集,则:
    • ε ε ε 属于某个 F I R S T ( α i ) FIRST(α_ i) FIRST(αi) a ∈ F O L L O W ( A ) a∈FOLLOW(A) aFOLLOW(A) ,则让 A与 ε ε ε 自动匹配。
    • 否则,a的出现是一种语法错误

7.4 FIRST和FOLLOW集合的构造

7.4.1 构造 F I R S T ( α ) FIRST(α) FIRST(α)

F I R S T ( α ) = { a ∣ α ⇒ ∗ a . . . , a ∈ V T } FIRST(\alpha)=\{a|\alpha ⇒^* a..., a \in V_T\} FIRST(α)={aαa...,aVT}

对于First集合的构造,可以由易到难进行考虑,首先考虑 α α α 为单个字符的情况,然后推广到任意长度的串:

{ α = X , X ∈ V T ∪ V N (单个文法符号) α = X 1 X 2 … X n , X i ∈ V T ∪ V N (任何符号串) \begin{cases} α= X,X∈V_T∪V_N & \text{(单个文法符号)}\\ α= X_1X_2…X_n,X_i∈V_T∪V_N & \text{(任何符号串)} \end{cases} {α=XXVTVNα=X1X2XnXiVTVN(单个文法符号)(任何符号串)

构造每个文法符号的FIRST集合

(思想:将无穷推导转化为对优先产生式的反复扫描)
构造每个文法符号的FIRST集合

构造任何符号串的FIRST集合

构造任何符号串的FIRST集合

这里的 F I R S T ( X i ) / { ε } FIRST(X_i) / \{ε\} FIRST(Xi)/{ε} 表示的是除去空字集合。

7.4.2 构造FOLLOW(A)

F O L L O W ( A ) = { a ∣ S ⇒ ∗ . . . A a . . . , a ∈ V T } FOLLOW(A)=\{a|S ⇒^* ...Aa..., a \in V_T\} FOLLOW(A)={aS...Aa...,aVT}

构造每个非终结符的FOLLOW集合

构造FOLLOW流程

对于第2点:解释

对于第3点:解释

7.4.3 练习

对于上面的文法G(E):

E → T E ′ E ′ → + T E ′ ∣ ε T → F T ′ T ′ → ∗ F T ′ ∣ ε F → ( E ) ∣ i \begin{aligned} &E→TE' \\ &E'→+TE'| ε \\ &T→FT' \\ &T'→*FT'| ε \\ &F→(E) | i \\ \end{aligned} ETEE+TEεTFTTFTεF(E)i

构造每个非终结符的FIRST和FOLLOW集合 :

根据前面构造FIRST集合的步骤:

FIRST第1步第2步第3步第4步
F I R S T ( E ) = FIRST(E)= FIRST(E)= { ( , i \{(,i {(,i { ( , i } \{(,i\} {(,i}
F I R S T ( E ′ ) = FIRST(E')= FIRST(E)= { + , ε \{+, ε {+,ε { + , ε \{+, ε {+,ε { + , ε \{+, ε {+,ε { + , ε } \{+, ε\} {+,ε}
F I R S T ( T ) = FIRST(T)= FIRST(T)= { ( , i \{(, i {(,i { ( , i \{(, i {(,i { ( , i } \{(, i\} {(,i}
F I R S T ( T ′ ) = FIRST(T')= FIRST(T)= { ∗ , ε \{*, ε {,ε { ∗ , ε \{*, ε {,ε { ∗ , ε \{*, ε {,ε { ∗ , ε } \{*, ε\} {,ε}
F I R S T ( F ) = FIRST(F)= FIRST(F)= { ( , i \{(, i {(,i { ( , i \{(, i {(,i { ( , i \{(, i {(,i { ( , i } \{(, i\} {(,i}

有了FIRST集合,就可以构造FOLLOW集合(注意一个产生式可能有不同的匹配规则匹配):

  • 第一次处理时加入 # \# #
  • 满足: A → α B β A\to \alpha B \beta AαBβ ,将 F I R S T ( β ) / { ε } FIRST(\beta)/\{ε\} FIRST(β)/{ε} 加入到 F O L L O W ( B ) FOLLOW(B) FOLLOW(B)
  • 满足: A → α B β A\to \alpha B \beta AαBβ ,且 β ⇒ ∗ ε \beta ⇒^*ε βε F O L L O W ( A ) FOLLOW(A) FOLLOW(A) 加入到 F O L L O W ( B ) FOLLOW(B) FOLLOW(B)
  • 满足: A → α B A \to \alpha B AαB , 将 F O L L O W ( A ) FOLLOW(A) FOLLOW(A) 加入到 F O L L O W ( B ) FOLLOW(B) FOLLOW(B)
  • 对于 ε ε ε 不处理
FOLLOW第1步对E处理第2步对E’处理第3步对T处理第4步对T’处理第5步对F处理第6步对E再处理第7步对T再处理之后继续几次直到发现各集合大小都不变
F O L L O W ( E ) = FOLLOW(E)= FOLLOW(E)= { # , \{\#, {#, { # , \{\#, {#, { # , \{\#, {#, { # , \{\#, {#, { # , ) , \{\#,), {#,), { # , ) , \{\#,), {#,), { # , ) , \{\#,), {#,), { # , ) } \{\#,)\} {#,)}
F O L L O W ( E ′ ) = FOLLOW(E')= FOLLOW(E)= { # , \{\#, {#, { # , \{\#, {#, { # , \{\#, {#, { # , \{\#, {#, { # , \{\#, {#, { # , ) , \{\#,), {#,), { # , ) , \{\#,), {#,), { # , ) } \{\#,)\} {#,)}
F O L L O W ( T ) = FOLLOW(T)= FOLLOW(T)= { + , # , \{+, \#, {+,#, { + , # , \{+, \#, {+,#, { + , # , \{+, \#, {+,#, { + , # , \{+, \#, {+,#, { + , # , \{+, \#, {+,#, { + , # , ) , \{+, \#,), {+,#,), { + , # , ) , \{+, \#,), {+,#,), { + , # , ) } \{+, \#,)\} {+,#,)}
F O L L O W ( T ′ ) = FOLLOW(T')= FOLLOW(T)= { + , # , \{+, \#, {+,#, { + , # , \{+, \#, {+,#, { + , # , \{+, \#, {+,#, { + , # , \{+, \#, {+,#, { + , # , ) \{+, \#,) {+,#,) { + , # , ) } \{+, \#,)\} {+,#,)}
F O L L O W ( F ) = FOLLOW(F)= FOLLOW(F)= { ∗ , + , # , \{*,+,\#, {,+,#, { ∗ , + , # , \{*,+,\#, {,+,#, { ∗ , + , # , \{*,+,\#, {,+,#, { ∗ , + , # , \{*,+,\#, {,+,#, { ∗ , + , # , ) , \{*,+,\#,), {,+,#,), { ∗ , + , # , ) } \{*,+,\#,)\} {,+,#,)}

第8章-自上而下分析2

8.1 构造递归下降分析器

8.1.1 递归下降分析器

  • 分析程序由一组子程序组成,对每一 语法单位 (非终结符)构造一个相应的 子程序 ,识别对应的 语法单位
  • 通过子程序间的相互调用实现对输入串的识别,例如,A → B c D 就有三个处理A、B、D的子程序
  • 文法的定义通常是递归的,通常具有递归结构
定义全局过程和变量
  • ADVANCE ,把输入串指示器IP指向下一个输入符号, 即读入一个单词符号
  • SYM ,IP当前所指的输入符号
  • ERROR ,出错处理子程序

每个非终结符有对应的子程序的定义,在分析 过程中,当需要从某个非终结符出发进行展开 (推导)时,就调用这个非终结符对应的子程序

8.1.2 递归下降子程序设计

一个简单的子程序的设计

简单个一个子程序设计

框内的代码不简化可以写成这样:

ELSE IF SYM ∈ FOLLOW(A) THEN
	BEGIN END
ELSE ERROR

一个例子

8.2 扩充的巴科斯范式和语法图

8.2.1 扩充的巴科斯范式

在元符号“→”或“::=”和“|”的基础上,扩 充几个元语言符号:

  • 用花括号 α {α} α 表示闭包运算 α ∗ α^* α
  • 用表示 α 0 n {α}_0^n α0n 可任意重复0次至n次。
  • 用方括号 [ α ] [α] [α] 表示 { α } 0 1 \{α\}_0^1 {α}01,即表示 α α α 的出现可有可无(等 价于 α ∣ ε α|ε αε )。

例如,通常的“实数”可定义为:

D e c i m a l → [ S i g n ] I n t e g e r . { d i g i t } [ E x p o n e n t ] E x p o n e n t → E [ S i g n ] I n t e g e r I n t e g e r → d i g i t { d i g i t } S i g n → + ∣ − \begin{aligned} & Decimal→[Sign]Integer.\{digit\}[Exponent] \\ & Exponent→E[Sign]Integer \\ & Integer→digit\{digit\} \\ & Sign→ + |- \\ \end{aligned} Decimal[Sign]Integer.{digit}[Exponent]ExponentE[Sign]IntegerIntegerdigit{digit}Sign+

用扩充的巴科斯范式来描述语法,直观易懂, 便于表示左递归消去和因子提取。

8.2.2 语法图

可以将最上面的文法转化为扩充巴科斯范式以及对应的语法图:

语法图

这样转化后的文法对应的递归子程序可以写成:
递归子程序

8.3 JavaCC简介

一个语法分析的小工具:
Java CC

第9讲 语法分析——自上而下分析3

9.1 预测分析程序

9.1.1 预测分析程序的工作原理

预测分析程序构成
  • 总控程序,根据现行栈顶符号和当前输入符号, 执行动作
  • 分析表M[A, a]矩阵 A ∈ V N , a ∈ V T A ∈V_N,a ∈V_T AVNaVT 是终 结符或 ′ # ′ '\#' #
  • 分析栈STACK 用于存放文法符号

预测分析程序的构成

预测分析过程

分析开始

总控程序根据当前栈顶符号X和输入符号a,执行下列三动作之一:
分析过程

  • 若X=a=‘#’,则宣布分析成功,停止分析。
  • 若X=a ≠‘#’,则把X从STACK栈顶逐出,让a指向 下一个输入符号。
  • 若X是一个非终结符,则查看分析表M。
    • 若M[X,a]中存放着关于X的一个产生式,把X逐出 STACK栈顶,把产生式的右部符号串按反序一一推进 STACK栈(若右部符号为ε,则意味不推什么东西进栈)。
    • 若M[X,a]中存放着“出错标志”,则调用出错诊察程序ERROR。
总控程序实现

总控程序实现

预测分析示例

对于上面的文法的一个预测分析的过程,其中分析表的构造看下一讲:
预测分析的实例

9.2 预测分析表的构造

9.2.1 分析表M[A,a]的构造

构造分析表前,首先要构造FIRST(α)和FOLLOW(A)

分析表M[A,a]的构造算法

构造G的分析表 M [ A , a ] M[A,a] M[Aa] ,确定每个产生式 A → α A→α Aα 在表中的位置:

  • 1 对文法G的每个产生式 A → α A→α Aα 执行第2步和第3步;
  • 2 对每个终结符 a ∈ F I R S T ( α ) a ∈FIRST(α) aFIRST(α) ,把 A → α A→α Aα 加至 M [ A , a ] M[A, a] M[Aa] 中;
  • 3 若 ε ∈ F I R S T ( α ) ε∈FIRST(α) εFIRST(α) ,则对任何 b ∈ F O L L O W ( A ) b∈FOLLOW(A) bFOLLOW(A) A → α A→α Aα 加至 M [ A , b ] M[A,b] M[Ab] 中。
  • 4 把所有无定义的 M [ A , a ] M[A,a] M[Aa] 标上“出错标志”。

一个例子

9.2.2 LL(1)文法与二义性

  • 如果G是左递归或二义的,那么,M至少含有 一个多重定义入口。因此,消除左递归和提取 左因子将有助于获得无多重定义的分析表M。
  • 可以证明,一个文法G的预测分析表M不含多 重定义入口,当且仅当该文法为LL(1)的。
  • LL(1)文法不是二义的。

例如这样一个实现 ifelse 语句的文法就是二义性的,解决方法是人为的确定一个ifelse 语法,如就近匹配选择 S ′ → e S S'\to eS SeS

二义性
习题
(end)
https://blog.csdn.net/pi31415926535x/article/details/105163345

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这个里面的都是测试数据,总共得分5分。从控制台输入,不能从文件中读取。实现了基本功能,加分项目都没有去实现,没有函数数组这些的实现。这是用C++语言写的,新建parser类别要选C++,其他对于VS的配置和C语言一样。for语句用的是枚举所有情况,你可以自行修改。 对预备工作中自然语言描述的简化C编译器的语言特性的语法,设计上下文无关文法进行描述 借助Yacc工具实现语法分析器 考虑语法树的构造: 1.语法树数据结构的设计:节点类型的设定,不同类型节点应保存哪些信息,多叉树的实现方式 2.实现辅助函数,完成节点创建、树创建等功能 3.利用辅助函数,修改上下文无关文法,设计翻译模式 4.修改Yacc程序,实现能构造语法树的分析器 考虑符号表处理的扩充 1.完成语法分析后,符号表项应增加哪些标识符的属性,保存语法分析的结果 2.如何扩充符号表数据结构,Yacc程序如何与Lex程序交互,正确填写符号表项 以一个简单的C源程序验证你的语法分析器,可以文本方式输出语法树结构,以节点编号输出父子关系,来验证分析器的正确性,如下例: main() { int a, b; if (a == 0) a = b + 1; } 可能的输出为: 0 : Type Specifier, integer, Children: 1 : ID Declaration, symbol: a Children: 2 : ID Declaration, symbol: b Children: 3 : Var Declaration, Children: 0 1 2 4 : ID Declaration, symbol: a Children: 5 : Const Declaration, value:0, Children: 6 : Expr, op: ==, Children: 4 5 7 : ID Declaration, symbol: a Children: 8 : ID Declaration, symbol: b Children: 9 : Const Declaration, value:1, Children: 10: Expr, op: +, Children: 8 9 11: Expr, op: =, Children: 7 10 12: if statement, Children: 6 11 13: compound statement, Children: 3 12
R语言实战笔记九章介绍了方差分析的内容。方差分析是一种用于比较两个或多个组之间差异的统计方法。在R语言中,可以使用lm函数进行方差分析的回归拟合。lm函数的基本用法是: myfit <- lm(I(Y^(a))~x I(x^2) I(log(x)) var ... [-1],data=dataframe 其中,Y代表因变量,x代表自变量,a代表指数,var代表其他可能对模型有影响的变量。lm函数可以拟合回归模型并提供相关分析结果。 在方差分析中,还需要进行数据诊断,以确保模型的可靠性。其中几个重要的诊断包括异常观测值、离群点和高杠杆值点。异常观测值对于回归分析来说非常重要,可以通过Q-Q图和outlierTest函数来检测。离群点在Q-Q图中表示落在置信区间之外的点,需要删除后重新拟合并再次进行显著性检验。高杠杆值点是指在自变量因子空间中的离群点,可以通过帽子统计量来识别。一般来说,帽子统计量高于均值的2到3倍即可标记为高杠杆值点。 此外,方差分析还需要关注正态性。可以使用car包的qqplot函数绘制Q-Q图,并通过线的位置来判断数据是否服从正态分布。落在置信区间内为优,落在置信区间之外为异常点,需要进行处理。还可以通过绘制学生化残差的直方图和密度图来评估正态性。 综上所述,R语言实战第九章介绍了方差分析及其相关的数据诊断方法,包括异常观测值、离群点、高杠杆值点和正态性检验。这些方法可以用于分析数据的可靠性和模型的适应性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [R语言实战笔记--第章 OLS回归分析](https://blog.csdn.net/gdyflxw/article/details/53870535)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值