文法也可以通俗易懂

一直都说编织知识网,利用已有的节点去建立新的节点,但是一直做的不好,今天看到对文法解释的这个例子,真真切切的体会到了编织知识网给我们带来的巨大好处。

文法给你的印象什么样的?抽象?晦涩?不知所云?神马终结符、字母表、产生式、闭包、自动机……晕死

但是看完下面的例子,你会感叹:原来这就是文法!

文法就是用来描述语言的语法结构的形式规则,所以先有这样一个认识,文法就是语法

例子(摘自:软件设计师考试):

张三和李四是工程师。

由5个词组成:张三 和 李四 是 工程师

组成一个句子:由主语、谓语构成。我们知道中文的文法:

<句子> --> <主语> <谓语>

<主语> -- > <名词词组>

<名词词组> --> <名词> <连词> <名词词组>

<谓语> --> < 动宾词组>

<动宾词组> --> <动词> <宾语>

<宾语> --> <名词>

<名词> -->  张三丨李四丨工程师

<连词> --> 和

<动词> --> 是

在上面的例子中,所有用<>包括起来的都是“非终结符”,而所有直接写出来的就是“终结符”,以上规则就是“产生式”。

基于上述说法,现在看下面的概念

非终结符:它不是语言的组成部分,而是在推导过程中的占位符,最终要替换成终结符。

终结符:语言是组成部分,是最后的内容。

产生式:用终结符替代非终结符的规则。

起始符:能够用于语言开头的符号,在本例中的<主语>就是起始符。

原本晦涩难懂的概念,是不是一下清晰了很多。

根据上面的产生式,下面我们来看句子是如何被推导出来的:

<句子> => <主语><谓语>

=> <名词词组><谓语>

=> <名词><连词><名词词组><谓语>

=> <名词><连词><名词词组><动宾词组>

=> <名词><连词><名词词组><动词><名词>

=> 张三和李四是工程师

我们从中可以发现,它也可以推导出“张三和工程师是李四”,这句话是符合语法的,但是语义有问题,所以语法的分析只能发现语法上的错误。

那么联想一下,词法分析呢?还记得我们经常分析的问题吗?

(0|1)*01这是一个由0、1组成的字符串,并且以01结尾。所以不难想到,程序编译时怎么判断变量的命名是否准确呢?构造一个以字母、下划线开头,由字母、下划线、数字组成的有限自动机即可。

时间: 2024-08-01 17:38:07

文法也可以通俗易懂的相关文章

LL(1)文法分析表的构造和分析过程示例

在考完编译原理之后才弄懂,悲哀啊.不过懂了就好,知识吗,不能局限于考试. 文法: E→TE' E'→+TE'|ε T→FT ' T'→*FT'|ε F→id| (E) 一.首先判断是不是 LL(1)文法 -------------------------------------------------------------------------------------------------------- 文法G的任意两个具有相同左部的产生式 A --> α|β 满足下列条件: 1.如果α和

使用Scala基于词法单元的解析器定制EBNF范式文法解析

一.前言 近期在做Oracle迁移到Spark平台的项目上遇到了一些平台公式翻译为SparkSQL(on Hive)的需求,而Spark采用亲妈语言Scala进行开发.分析过大概需求过后,拟使用编译原理中的EBNF范式模式,进行基于词法的文法解析.于是拟采用传统的正则词法解析到EBNF文法解析的套路来实现,直到发现了StandardTokenParsers这个Scala基于词法单元的解析器类. 二.平台公式及翻译后的SparkSQL 平台公式的样子如下所示: 1 if(XX1_m001[D003

文法改进(消除左递归)

在上次的文法中有存在左递归的情况,将会影响以后的语法分析使用,所以需要消除左递归,以便于语法分析使用. <程序> → <外部声明> <程序>` <程序>`→<程序> | ε <外部声明> → <函数定义> | <定义> <函数定义> → <函数声明> <函数体> <函数声明> → <函数返回类型> <函数头> <函数返回类型>

python装饰器通俗易懂的解释!

python装饰器 刚刚接触python的装饰器,简直懵逼了,直接不懂什么意思啊有木有,自己都忘了走了多少遍Debug,查了多少遍资料,猜有点点开始明白了.总结了一下解释得比较好的,通俗易懂的来说明一下: 小P闲来无事,随便翻看自己以前写的一些函数,忽然对一个最最最基础的函数起了兴趣: 1 def sum1(): 2 sum = 1 + 2 3 print(sum) 4 sum1() 此时小P想看看这个函数执行用了多长时间,所以写了几句代码插进去了: 1 import time 2 3 def

1014 C语言文法定义与C程序的推导过程 程序:冒泡算法C程序(语法树)

1014 C语言文法定义与C程序的推导过程  程序:冒泡算法C程序(语法树)1 阅读并理解提供给大家的C语言文法文件. 2 参考该文件写出一个自己好理解版的现实版的完整版的C语言文法. 3 给出一段C程序,画出用上述文法产生这段C程序的完整语法树. 程序:冒泡算法C程序 点此文字查看原图(完整图片) 1 #include <stdio.h> 2 3 main() 4 { 5 int i,j,temp; 6 int a[10]; 7 8 for(i=0;i<10;i++) 9 scanf

求LR(0)文法的规范族集和ACTION表、GOTO表的构造算法

原理 数据结构 1 // GO 2 private static Map<Map<Integer,String>,Integer> GO 3 = new HashMap<Map<Integer,String>,Integer>(); 4 5 // 规范族集 C 6 private static Map<Integer,Map<String,List<String>>> C 7 = new HashMap<Intege

Java文法(7)—Literals

----------------------------------------------------------------------------------------------------------------------------------- 说明: A literal is the source code representation of a value of a primitive type (§4.2), the String type (§4.3.3), or th

Java文法(6)—keywords

-------------------------------------------------------------------------------------------------------------------------- 说明: 50 character sequences, formed from ASCII letters, are reserved for use as keywords and cannot be used as identifiers (§3.8

Java文法(5)—Identifier

---------------------------------------------------------------------------------------------------------------- 说明: An identifier is an unlimited-length sequence of Java letters and Java digits, the first of which must be a Java letter. ------------