编译原理----词法分析设计

2023-05-16

程序设计实验1 词法分析

一、实验目的:

通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。

二、实验内容

编制一个单词获取程序,从文件输入的源程序中,识别出各个具有独立意义的单词,即关键字、标识符、整数、小数、字符串、字符、分隔符、运算符等八大类。

三、实验要求

1、词法规则
关键字: void、var、int、float、string、begin、end 、if、then、else、while、do、call、read、write、and、or
单词类别:1 注意:关键字大小敏感(区分大小写)。

标识符: 字母或 “ $ ” 打头、由字母、数字串或“$”组成的任意长度的符号串。
单词类别:2 注意:标识符大小敏感(区分大小写)。

整数: 数字串。
单词类别:3

小数: 数字串1. 数字串2
单词类别:4 注意:数字串1不能为空,数字串2可以为空,例如:23.

字符串: 由一对“”括起来的任意长度的符号串。注意:可以多行。
单词类别:5

字符: 由一对单引号括起来的单个字母。如:‘a’、‘5’、‘+’
单词类别:6

分隔符: {、}、(、)、;、空格
单词类别:7

运算符: ==、=、<、<=、>、>=、<>、+、-、*、/
单词类别:8

注释: 支持单行注释和多行注释(注释语法同C语言)。
为了实现的编译程序实用,这里规定源程序可采用自由书写格式,即一行内可以书写多个语句,一个语句也可以占领多行书写。

2、设计要求
(1)设计一个主程序,通过人机交互的方式或命令行参数获得需要分析的源代码文件,打开待分析的源程序,通过反复调用词法分析程序逐个获得源代码中的所有单词并输出。
整个程序的总体流程见图1-1。
(2)设计一个词法分析器,其输入为要分析的源文件,每次调用顺序识别出源文件中的下一个单词。每个单词需要输出:单词本身、单词类别、单词所在的行列号。遇到错误时可显示“Error”,然后跳过错误部分继续显示。
注意:在主程序中输出单词的信息,词法分析中不能输出单词信息,只能通过返回值或全局变量返回所提取的单词信息。
(3)实验结束后提交源代码、测试数据、实验报告至:
ftp://编译原理/程序设计1
本次实验提交的截止日期:2023-04-15 晚22:00 前.
(4)实验报告内容:(具体参见“编译原理程序设计实验报告模版.docx”)
(a) 有关词法分析器设计的说明。详细说明词法分析器的实现原理,包括软件结构设计说明、功能模块说明、关键数据结构说明、关键算法实现等。
(b) 给出词法分析器源程序清单,并标记出每个模块的功能;
© 说明词法分析器中可能存在的问题;
(d) 经验总结,如果重做一遍,你会有哪些新的改进?

四、实验过程和指导

(一)准备:
1、阅读课本有关章节,明确语言的语法,写出基本保留字、标识符、常数、运算符、分隔符和程序例。
2、初步编制好程序。
3、准备好多组测试数据,包括正确的输入和错误的输入。

(二)程序要求:
程序输入/输出示例:
如源程序为C语言。输入如下一段:
void main()
{
int a,b;
a = 10;
b = a + 20;
}

要求输出如下所示,每个单词输出:单词类型、单词本身、行号、列号。
(1,void,1, 1)
(2,main, 1, 6)
(7, ( ,1,10)
(7, ),1,11)
(7, { ,2, 1)
(1, int,3, 4)
(2, a ,3, 8)
(…

(三)设计指导:
词法分析程序的主要工作为:
(1)从源程序文件中逐个读入字符。
(2)统计行数和列数用于错误单词的定位。
(3)删除空格类字符,包括回车、制表符空格。
(4)根据每个单词的首字符确定该单词的类型,按构词规则从源文件中逐个读入字符检查该字符是否该单词的允许输入。
在编写词法分析程序时,用重复调用词法分析子程序取一单词的方法得到整个源程序的单词序列。
整个程序的总体流程见图1-1。
词法分析程序的流程图见图1-2。
取字符和统计字符行列位置子程序见图1-3。
注意:图1-2、图1-3仅供参考,并不完全符合本次实验的要求,仅仅说明整个词法分析程序的总体框架。因此,实验报告中不能直接贴图1-1、图1-2、图1-3,否则实验报告以无效处理。

图
图1-1

在这里插入图片描述



源代码:
import java.util.Arrays;
import java.util.Scanner;
import java.util.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.regex.Pattern;

class Results{//保存要输出的结果
    boolean rig;//是否是错误
    int type;//记录类型
    String res;//输出内容
    int li=0,co=0;//所在行和列
}
public class Main {
    static final int N=101;//定义一个常量,当输入增多时便于后续修改
    static int a[]=new int [N];//该数组用来存放文本每行的列数(假设输入数据不超过100行)
    static boolean ok=false;//记录每行第一个单词前是否有空格,如果有为true
    static boolean mark=false;//如果判断出是注释的内容,是则为true,否则为false
    static boolean biu=false;//当存在多行注释时为true
    static int blank=0;//保存前面的空格数
    static int k=0,lines,cols;//lines用来记录是第几行,cols记录第几列,不赋初值时自动为0
    static int num=0;//记录每一行字符的个数
    static boolean words=false;//当由""引起来的字符串占多行时为true
    static String strs="";//保存多行字符串前面的内容
    static Results RE[]=new Results[N];//保存一行中遇到的字符
    static String keyWord[]={"void","var","int","float","string","begin","end","if",
            "then","else","while","do","call","read","write","and","or"};//1 关键字
    static String symbol[]={"{","}","(",")",";"," "};//7 分隔符
    static String operation[]={"==","=","<","<=",">",">=","<>","+","-","*","/"};//8 运算符
    static ArrayList<String> keyWords=null;//1 关键字
    static ArrayList<String> symbols=null;//7 分隔符
    static ArrayList<String> operations=null;//8 运算符

    //关键字,字母或$的识别   1 2
    public static void letterCheck(String str){
        cols=k+1;
        String token= String.valueOf(str.charAt(k++));
        char ch;
        for( ;k<str.length();k++){
            ch=str.charAt(k);
            if (!Character.isLetterOrDigit(ch)&&ch!='$')
                break;
            else
                token+=ch;
        }
        if(ok)
            cols+=blank;
        if (keyWords.contains(token)){
            RE[num].rig=true;RE[num].type=1;
            RE[num].res=token;RE[num].li=lines;RE[num].co=cols;
            ++num;
        }
        else{
            RE[num].rig=true;RE[num].type=2;
            RE[num].res=token;RE[num].li=lines;RE[num].co=cols;
            ++num;
        }
        if (k!=str.length()-1||(k==str.length()-1&&(!Character.isLetterOrDigit(str.charAt(k))&&str.charAt(k)!='$')))
            k--;
    }
    //数字的识别  3 4
    //1、识别退出:遇到空格符,遇到运算符或者界符   2、错误情况:两个及以上小数点,掺杂字母
    public static void digitCheck(String str){
        cols=k+1;
        String token= String.valueOf(str.charAt(k++));
        int flag=0;//记录小数点的个数
        boolean err=false;
        char ch;
        for( ;k<str.length();k++){
            ch=str.charAt(k);
            if(ch==' '||(!Character.isLetterOrDigit(ch)&&ch!='.')||
               symbols.contains(ch)||operations.contains(ch))//遇到空格,运算符或者标识符则退出,属于正常退出
                break;
            else if (err)
                token+=ch;
            else{
                token+=ch;
                if (ch == '.') {//这个if判断是否存在多个小数点的情况
                    if(flag>=1)//如果之前已经记录有一个小数点了,那么此时就是错误
                        err=true;
                    flag++;//只要遇到小数点就加一
                }
                else if (Character.isLetter(ch))//遇到字母时是不对的
                    err=true;
            }
        }
        if(token.charAt(token.length()-1)=='.'&&flag>=2)//如果最后的出的字符串最后一位是小数点,并且出现多个小数点则错误
            err=true;  //小数点前面不能为空,后面2可以为空
        if(err){
            RE[num].rig=false;RE[num].type=-1;
            RE[num].res=token;RE[num].li=lines;RE[num].co=cols;
            ++num;
        }
        else{
            if(ok)
                cols+=blank;
            if(flag==0) {//flag为0时说明没有小数点,数字串和小数要分开输出
                RE[num].rig=true;RE[num].type=3;
                RE[num].res=token;RE[num].li=lines;RE[num].co=cols;
                ++num;
            }
            else{
                RE[num].rig=true;RE[num].type=4;
                RE[num].res=token;RE[num].li=lines;RE[num].co=cols;
                ++num;
            }
        }
        if(k!=str.length()-1||(k==str.length()-1&&!Character.isDigit(str.charAt(k))))
            k--;
    }
    //字符串检查   5
    public static void stringCheck(String str){
        cols=k+1;
        String token=String.valueOf(str.charAt(k++));
        char ch;
        int n=str.length();
        if(!words){//直接寻找第一次分号的位置并记录下来,如果不加这个条件可能会被识别为第2次的
            for(int i=0;i<n;++i){
                if(str.charAt(i)=='"'){
                    RE[num].li=lines;
                    RE[num].co=i+1+(ok==true?blank:0);
                    break;
                }
            }
        }
        for( ;k<n;++k){
            ch=str.charAt(k);
            token+=ch;
            if(words==true&&ch=='"'){//多行结束情况判断,遇到引号结束,就把strs的值赋给token
                strs+=token;
                token=strs;//最后保存到RE中的是token,所以将strs的值赋给token
                words=false;//这里一定要置为false,否则后面对1,2的判断都不会出现
                break;
            }
            if(ch=='"')//单独一行就直接break就行了
                break;
        }
        if(token.charAt(token.length()-1)!='"') {//最后一个字符不是双引号说明是多行字符串,标记为true,直接返回继续判断
            words=true;
            strs+=token;
            return;
        }
        else{
            RE[num].type=5;
            RE[num].res=token;
            ++num;
        }
    }
    //单引号引起来字符的识别   6
    public static void charCheck(String str){
        cols=k+1;
        String token=String.valueOf(str.charAt(k++));
        char ch;
        int n=str.length();
        for( ;k<n;++k){
            ch=str.charAt(k);
            token+=ch;
            if(ch=='\'')//单个打印号要用转义字符表示
                break;
        }
        if(token.charAt(token.length()-1)!='\'') {//最后一个字符不是单引号
            RE[num].rig=false;RE[num].type=-1;
            RE[num].res=token;RE[num].li=lines;RE[num].co=cols;
            ++num;
        }
        else {//没有就可以输出是第几个类型的词,本身,行号和列号
            if(ok)
                cols+=blank;
            RE[num].rig=true;RE[num].type=6;
            RE[num].res=token;RE[num].li=lines;RE[num].co=cols;
            ++num;
        }
    }
    //分隔符,运算符的识别   7 8
    public static void symbolCheck(String str){
        cols=k+1;
        String token= String.valueOf(str.charAt(k++));
        char ch;
        if (symbols.contains(token)){//如果该符号包含在分隔符中,因为分隔符中都是单个符号,所以直接输出token
            if(ok)
                cols+=blank;
            RE[num].rig=true;RE[num].type=7;
            RE[num].res=token;RE[num].li=lines;RE[num].co=cols;
            ++num;
            k--;
        }
        else {
            if (operations.contains(token)){
                if (k<str.length()){
                    ch=str.charAt(k);

                    if(str.charAt(k)=='/'&&str.charAt(k-1)=='/'){//只要遇到单行注释,直接return就行,不用做标记
                        mark=true;
                        return;
                    }
                    if(str.charAt(k-1)=='/'&&str.charAt(k)=='*'){//当存在多行注释时,使biu为true
                        biu=true;
                        //return; 当在一行中找到/*符号时,可能这一行也会有*/符号,所以这个需要判断,不能直接返回
                    }
                    if(biu){//判断是不是会在当前这行注释结束
                        for(int i=k;i<str.length();++i){
                            if(str.charAt(i)=='*'&&str.charAt(i+1)=='/'){
                                biu=false;
                                k=i+1;//从多行注释结束的下一个字符开始分析
                                return;
                            }
                        }
                        return;//如果没在同一行结束,直接返回判断下一行就好了
                    }
                    if (operations.contains(token+ch)){//如果包含,说明该运算符由2个字符组成
                        token+=ch;
                        if(ok)
                            cols+=blank;
                        RE[num].rig=true;RE[num].type=8;
                        RE[num].res=token;RE[num].li=lines;RE[num].co=cols;
                        ++num;
                    }
                    else {//此情况说明只是单个字符的运算符
                        k--;
                        if(ok)
                            cols+=blank;
                        if(mark==false&&biu==false){
                            RE[num].rig=true;RE[num].type=8;
                            RE[num].res=token;RE[num].li=lines;RE[num].co=cols;
                            ++num;
                        }
                    }
                }
            }
            else {//错误
                k--;
                if(ok)
                    cols+=blank;
                RE[num].rig=false;RE[num].type=-1;
                RE[num].res=token;RE[num].li=lines;RE[num].co=cols;
                ++num;
            }
        }
    }

    public static void init(){//初始化把数组转换为ArrayList,容易查找
        keyWords=new ArrayList<>();
        operations=new ArrayList<>();
        symbols=new ArrayList<>();
        Collections.addAll(keyWords,keyWord);
        Collections.addAll(symbols,symbol);
        Collections.addAll(operations,operation);
    }
    public static void analyze(String str){
        k=0;
        char ch;
        str=str.trim();//去掉每一行前后的空格
        int n=str.length();
        if(biu){//判断是不是会在下一行注释结束
            for(int i=0;i<n-1;++i){
                if(str.charAt(i)=='*'&&str.charAt(i+1)=='/'){
                    biu=false;
                    k=i+2;//从多行注释结束的下一个字符开始分析
                    break;
                }
            }
        }
        if(biu)
            return;//如果当前没有多行注释结束标志,说明这一行还是注释,直接跳过
        for ( ;k<str.length();k++){
            ch=str.charAt(k);
            if (Character.isDigit(ch))
                digitCheck(str);//3 4
            else if((words==false)&&(Character.isLetter(ch)||ch=='$'))//多行字符串时不能被1,2判断
                letterCheck(str);//1 2
            else if (words==true||ch=='"')//多行字符串的情况或者双引号开头都要归为第5类判断
                stringCheck(str);//5
            else if(ch=='\'')
                charCheck(str);//6
            else if (ch==' ')
                continue;
            else {
                symbolCheck(str);//7 8
                if(mark||biu)
                    return;
            }

        }
    }

    public static void main(String[] args) {
        init();
        File file=new File("D:\\Java_code\\Beijing\\src\\score3.txt");
        try(Scanner in=new Scanner(file)) {
            while (in.hasNextLine()){
                String str=in.nextLine();//每次读取一行
                cols=0;//每一次换行的列数 都要从头计数
                ok=false;
                mark=false;//每一行新判断的时候都应该把注释记录清空
                //biu=false;  多行注释的消除只能通过再一次遇到*/才行,不是每次循环设为false
                //只要出现2个斜杠它后面就得是注释,不管后面还有啥,2个斜杠是肯定把后面的东西都注释掉了
                if(!words){//当有多行字符串时,要保存之前的行和列,所以就不对其清零了。并且数组也不从0开始保存
                    num=0;//表示一行中分析到词的个数
                    for(int i=0;i<N;++i){
                        RE[i]=new Results();//必须要先对每一个对象先实例化之后再对其赋值,否则会报空指针的错误
                        RE[i].rig=true;RE[i].type=0;
                        RE[i].res="";RE[i].li=0;RE[i].co=0;
                    }
                }
                int len=str.length();
                a[++lines]=len;//用数组存放每一行有多少列
                if(str.trim().length()!=a[lines]) {//如果前面有空格,就先把相差的空格数记上
                    blank=(a[lines] - str.trim().length());
                    ok=true;//只有开头有空格时ok才为true,在句子中时或者句子前没空格时ok为false
                }
                analyze(str);
                for(int i=0;i<num;++i){//在主函数中输出信息
                    if(RE[i].rig)
                        System.out.println("("+RE[i].type+","+RE[i].res+","+RE[i].li+","+RE[i].co+")");
                    else
                        System.out.println(RE[i].li+"line"+": "+RE[i].res+" Error");
                }
            }
        }
        catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }
}


在这里插入图片描述
图1-1 总体架构设计


在这里插入图片描述
图1-2 词法分析程序


在这里插入图片描述

图1-3 取字符和统计字符行列位置



时间:2023年5月12日17:12:42
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

编译原理----词法分析设计 的相关文章

  • 《图解深度学习》学习笔记(一)

    第一章 绪论 监督学习 xff1a 需要基于输入数据及其期望输出 xff0c 通过训练从数据中提取通用信息或特征信息 特征值 xff0c 以此得到预测模型 这里的特征值是指根据颜色和边缘等认为定义的提取方法从训练样本中提取的信息 xff08
  • 3D点云基础知识(一)-初始入门-知乎整理(一)

    本文基于如下知乎文章 xff0c 调整部分内容整理输出 xff0c 一为梳理基础知识 xff0c 二为致敬原作 作者 xff1a Mr 苍雪 链接 xff1a https zhuanlan zhihu com p 344635951 来源
  • Open3D处理点云数据(一)点云文件读取、写入、显示

    import open3d as o3d import numpy as np pcd 61 o3d geometry PointCloud pcd类型的数据 np points 61 np random rand 100 3 随机生成点云
  • Ubuntu非管理员root安装ninja:解决RuntimeError: Ninja is required to load C++ extensions错误

    服务器是共用的 xff0c 所以无法使用sudo apt get 命令快速安装 只能自己下载git上的源代码然后编译 xff0c 装在自己的私人目录下 否则 sudo apt get 安装很容易 xff0c 55555555 Ninja是一
  • Elasticsearch相似度算分TF-IDF BM25(标贝科技)

    欢迎体验标贝语音开放平台 地址 xff1a https ai data baker com source 61 qaz123 xff08 注 xff1a 填写邀请码hi25d7 xff0c 每日免费调用量还可以翻倍 xff09 控制相关度
  • 【K210】K210学习笔记五——串口通信

    K210 K210学习笔记五 串口通信 前言K210如何进行串口通信K210串口配置K210串口发送相关定义K210串口接收相关定义K210串口发送接收测试 完整源码 前言 本人大四学生 xff0c 电赛生涯已经走到尽头 xff0c 一路上
  • C++类与对象笔记十二:运算符重载三:递增运算符重载

    先看看系统自带的递增运算符 43 43 递增运算符重载 43 43 xff1b a 43 43 43 43 a int a 61 10 cout lt lt 43 43 a lt lt endl 11 先加 xff0c 后输出 cout l
  • C++类与对象笔记十四:多态六:虚析构和纯虚析构

    多态使用时 xff0c 如果子类中有属性开辟到堆区 xff0c 那么父类指针在释放时无法调用子类的析构代码 即 xff1a 父类指针无法调用子类实例对象内的析构函数 造成堆区内存泄漏 解决方案 将父类中的析构函数改为虚析构或者纯虚析构 虚析
  • PCL笔记九:采样一致性

    模型拟合 xff1f 采样一致性的目的 xff1a 用于排除错误的样本 基于采样一致性算法的应用主要是对点云进行分割 xff0c 根据不同设定的几何模型 xff0c 估计对应的几何模型的参数 xff0c 在一定允许误差范围内分割出在模型上的
  • ubuntu下安装gfortran

    找官网 xff1a GFortranBinaries GCC Wiki 找到GNU Linux 找到Download xff0c 点击蓝色链接下载 此外有installtion instructions安装步骤 Gfortran Binar
  • 面试可能会问六:智能指针

    先看一下百度百科的解释 xff1a 指针指针 当类中有指针成员时 xff0c 一般有两种方式来管理指针成员 xff1a 一是采用值型的方式管理 xff0c 每个类对象都保留一份指针指向的对象的拷贝 xff1b 另一种更优雅的方式是使用智能指
  • C++笔记:指针转向(重新赋值)时的问题;重复释放;原地址遗漏释放;赋值运算符重载operator=;

    一个类默认会创建4个函数 xff1a 默认构造 拷贝构造 析构 和operator 61 函数 最后一个就是赋值运算符重载 xff0c 可以进行简单的值传递 注意 xff1a 这个是值传递 问题就在这 xff1b 还有一种传递叫 xff1a
  • C++笔记:虚继承

    虚继承解决的是菱形继承 Animal下派生出Sheep和Tuo类 动物基类下 xff0c 有两个派生类 xff0c 一个是羊类 xff0c 一个是驼类 这两个类都继承了Animal的一个属性 xff0c 比如m age 这样就导致资源的浪费
  • Ubuntu 搭建文件服务器(Nginx)

    1 xff0c 下载Nginx 2 xff0c 安装Nginx 3 xff0c Nginx指令及脚本使用 4 xff0c 配置Nginx 1 xff0c 下载Nginx 去官网下载对应的Nginx版本 nginx download 直接在u
  • WS2812灯珠(四)---实现全彩呼吸灯效果

    WS2812灯珠实现呼吸灯效果主要涉及到呼吸函数及颜色模型两部分的内容 清楚了这两点结合之前的灯珠驱动程序 xff0c 便可以实现任意颜色的呼吸变换效果了 呼吸函数 具体的呼吸函数细节这里就不介绍了 xff0c 感兴趣的可以自行搜索 这里下
  • 浅谈Marlin2.0

    简介 marlin固件发展至今已经形成了三个比较重大的版本 xff1a 1 0版 xff0c 1 1版 xff0c 2 0版 我接触marlin固件已经有一段时间了 xff0c 原来一直对于marlin固件的结构和应用平台一直不是很理解 x
  • uni-app多平台融合【入门】(标贝科技)

    标贝科技 https ai data baker com source 61 qwer12 填写邀请码fwwqgs xff0c 每日免费调用量还可以翻倍 uni app多平台融合 入门 标贝科技 xff09 一 uni app介绍 uni
  • vscode开发STM32(三)---调试篇

    vscode开发STM32 xff08 三 xff09 调试篇 文章目录 vscode开发STM32 xff08 三 xff09 调试篇前提条件配置调试配置JLink使用 96 JLinkGDB 96 进行调试配置stlink使用openO
  • CANopen资料收集

    CANopen资料收集 文章目录 CANopen资料收集开源CANopen协议栈1 CanFestival2 CANopenNode 3 canopen stack CIA官网canopen说明 https www can cia org
  • Modbus资料收集

    Modbus资料收集 文章目录 Modbus资料收集开源Modbus协议栈1 FreeModbus2 uc Modbus 开源Modbus协议栈 1 FreeModbus 网站 xff1a https www embedded expert

随机推荐

  • CANopenNode学习笔记(一)--- README翻译

    CANopenNode学习笔记 文章目录 CANopenNode学习笔记特性CANopen其他 CANopenNode 流程图文件结构对象字典编辑器 CANopenNode 是免费开源的CANopen协议栈 CANopen是建立在CAN基础
  • STM32驱动MAX6675读取K型热电偶温度

    MAX6675 进行热电偶冷端补偿和数字化 K 型热电偶信号 输出 12 位分辨率 SPI 兼容 只读的数据 转换器的精度为 0 25 xff0c 最高可读 43 1024 xff0c 如果使用数据的 8LSB 则温度范围为 0 到 43
  • WS2812灯珠(二)-- STM32 SPI+DMA方式驱动

    通过硬件SPI的可以很巧妙的模拟出WS2812的通信时序 xff0c 用spi的8位数据模拟ws281x的一位数据 要将系统时钟设置为56M xff0c SPI分频数设置为8 xff0c 则SPI的通信频率为7M xff0c 1s 7M 1
  • ESP8266(一)---引脚定义&接线说明

    一 引脚定义 xff1a FunctionDescriptionURXDUART RXD xff0c 接收UTXDUART TXD xff0c 发送RST外部Reset信号 xff0c 低电平复位 xff0c 高电平工作 xff08 默认高
  • STM32编码器模式详解(一)---理论

    一 编码器接口模式 选择编码器接口模式的方法是 xff1a 如果计数器只在TI2的边沿计数 xff0c 则置TIMx SMCR寄存器中的SMS 61 001 xff1b 如果只在TI1边沿计数 xff0c 则置SMS 61 010 xff1
  • STM32使用虚拟示波器

    STM32使用虚拟示波器 在调试过程中 xff0c 经常会有需要看到数据实时变化的情况 xff0c 这时候便需要用到虚拟示波器 如 xff1a 制作平衡车时 xff0c 需要了解拟合角度跟随加速度计和陀螺仪的动态变化情况 xff1b 做电机
  • STM32驱动多个超声波模块(只用一个定时器)

    用STM32单片机成功驱动一个超声波模块后 xff0c 接下来便有了疑问如何用stm32单片机驱动多个超声波模块呢 xff1f xff08 驱动一个超声波模块可以参考 xff1a stm32驱动超声波模块测距 xff09 超声波模块型号为H
  • 《SPARK官方教程系列》(标贝科技)

    1 概述 Apache Spark是一个用于大规模数据处理的统一分析引擎 xff0c 它在Java Scala Python和R中的提供了高级api xff0c 以及一个支持通用执行图 general execution graphs 的优
  • linux 在Terminal中打开桌面中的文件夹 nautilus命令; mac 在Terminal中打开桌面中的文件夹 open命令

    图形用户界面 xff08 Graphical User Interface xff0c 简称GUI xff0c 又称图形用户接口 xff09 是指采用图形方式显示的计算机操作用户界面 一 xff0e 在Linux系统中 nautilus 打
  • C/C++文件的编译过程

    在Windows下使用VS VC等编译器 xff0c xff08 其实VS只是编码器 xff0c 在幕后是CL编译器在帮助其编译 xff09 编译C C 43 43 文件我们并不能直观的看到详细过程 xff0c 编译器直接自动编译 其实在L
  • 如何使用带有用户名密码认证的HTTP(S)代理?保姆级教程来了!

    当我们在日常应用HTTP代理的时候 xff0c 终端IP不固定的情况下 xff0c 或者需要多机器同时使用HTTP代理时 xff0c 就会遇到一个问题 xff1a 如何使用带有用户名密码认证的HTTP S 代理 xff1f 按照下列步骤 x
  • PotPlayer的官网

    访问 PotPlayer 的官网 xff0c 需要先能访问到外面的网络 http potplayer tv http potplayer daum net 如果无法访问外面的网络 xff0c 可以使用下面的阿里云盘链接 阿里云盘分享
  • 为什么C++支持重载而C语言不支持重载

    一个函数在C 43 43 中能够被重载 xff0c 但是在C语言确不能被重载的 xff0c 是由于函数名在内存中存储方式不同所导致的 C语言 例如在C语言中 xff0c 有以下三个函数 xff0c 只给声明不给定义 xff01 span c
  • 2020-08-07

    上拉电阻 画红框标记的就是上拉电阻 概念 xff1a 上拉电阻的概念就是一端连接电源正极 xff0c 一端连接到输出口 xff0c 如果没有这个电阻 xff0c 那么电源和输出口就没有直接连接关系 它的作用如上图 xff0c 它可以避免I
  • extern "C" 含义

    extern 34 C 34 含义 extern 34 C 34 被 extern 限定的函数或变量是 extern 类型的 被 extern 34 C 34 修饰的变量和函数是按照 C 语言方式编译和链接的 extern 34 C 34
  • 77. Combinations

    Given two integers n and k return all possible combinations of k numbers out of 1 n For example If n 61 4 and k 61 2 a s
  • 基于STM32的串口通讯

    基于STM32的串口通讯 设备之间通信的方式 串行通信一般是以帧格式传输数据 xff0c 即一帧一帧的传输 xff0c 每一帧都含有起始信号 xff0c 数据信息以及停止信息等 并行通信 数据各个位同时传输 xff0c 速度快 xff0c
  • C语言的艺术之——头文件

    好记性不如烂笔头o o 系列的文章 xff1a C语言的艺术之 头文件 C语言的艺术之 函数 C语言的艺术之 标识符命令与定义 C语言的艺术之 变量 C语言的艺术之 注释 C语言的艺术之 排版与格式 C语言的艺术之 安全性 编码原则 xff
  • 图像高斯分布生成

    给定一些标记点的坐标 xff0c 希望生成其在图像中的高斯分布图 首先 xff0c 上公式 xff1a 不造怎么上公式 嗯稍后学习学习再补充 span class hljs keyword import span numpy span cl
  • 编译原理----词法分析设计

    程序设计实验1 词法分析 一 实验目的 xff1a 通过设计编制调试一个具体的词法分析程序 xff0c 加深对词法分析原理的理解 并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法 二 实验内容 编制一个单词获取程序