返回顶部
首页 > 资讯 > 前端开发 > JavaScript >JavaScript词法都有哪些
  • 628
分享到

JavaScript词法都有哪些

2024-04-02 19:04:59 628人浏览 泡泡鱼
摘要

这篇文章将为大家详细讲解有关javascript词法都有哪些,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。InputElement 输入元素输入元素是js词

这篇文章将为大家详细讲解有关javascript词法都有哪些,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

InputElement 输入元素

输入元素是js词法扫描程序拿到的最基本元素了,也就是JS程序源代码中表达特定意义的"单词"。

输入元素共分为四种:

InputElement ::
    WhiteSpace
    Comment
    Token
    LineTerminator

值得注意的是,JS规范里面其实定义了两种InputElement ,如下所示

InputElementDiv ::
    WhiteSpace
    Comment
    Token
    LineTerminator
    DivPunctuator
InputElementRegExp ::
    WhiteSpace
    Comment
    Token
    LineTerminator
    RegularExpressionLiteral

这么做是因为JS的除法运算符和正则表达式直接量都使用了/字符,在词法分析阶段,是无法区分二者的。所以JavaScript的词法分析有两种状态,一种状态是扫描InputElementDiv,另一种状态是扫描InputElementRegExp,又所以,JS的词法分析器应该有两种状态,由语法分析器来设置,JavaScript的词法分析和语法分析必须交错进行。

学习web前端的过程中,难免会遇到很多的问题,这些问题可能会困扰你许久,为此我有个web开发学习交流群( 545667817 ),
里面都是  ITPUB  的小伙伴,并整理了一份最全面前端学习资料,从最基础的HTML+CSS+JS 到移动端HTML5的项目实战的学习资料都有整理,想学习的都可以申请加入,大家互相学习,互相交流,共同进步,每日分享不同的学习资料!

下面的一个例子说明了除法和正则表达式写法的冲突问题:

if(a+b)/a/g;
(a+b)/a/g;

可以看到完全相同的/a/g(而且前面一段字符也相同),可能被理解为除法或者正则表达式。因为必须区分所处的语法环境,所以单单靠词法分析无论如何也无法决定该用除法还是正则表达式来理解。

因为基本上没有任何编辑环境会对文本做语法分析,这个问题也造成了很多语法着色系统无法很好地处理JS正则表达式。

以非语言实现者的角度,完全应该按照最上面一段产生式去理解JS的词法。

WhiteSpace空白符

这个词相信不用细说,所有JS程序员都比较熟悉。JavaScript接受5种ASCII字符为空白符,BOM以及Unicode分类中所有属于whitespace分类的字符也可以作为空白符使用:

WhiteSpace ::
    <TAB>
    <VT>
    <FF>
    <SP>
    <NBSP>
    <BOM>
    <USP>

其中,<TAB>是U+0009,是缩进TAB符,也就是字符串中写的'\t'。

<VT>是U+000B,也就是垂直方向的TAB符'\v',这个字符在键盘上很难打出来,所以很少用到。

<FF>是U+000C,FORM Feed,分页符,字符串直接量中写作'\f',现代已经很少有打印源程序的事情发生了,所以这个字符在JS源代码中很少用到。

<SP>是U+0020,就是最普通的空格了。

<NBSP>是U+00A0,非断行空格,它是SP的一个变体,在文字排版中,可以避免因为空格在此处发生断行,其它方面和普通空格完全一样。多数的JS编辑环境都会把它当做普通空格(因为一般源代码编辑环境根本就不会自动折行……)

<BOM>是U+FEFF,这是ES5新加入的空白符,是Unicode中的零宽非断行空格,在以UTF格式编码的文件中,常常在文件首插入一个额外的U+FEFF,解析UTF文件的程序可以根据U+FEFF的表示方法猜测文件采用哪种UTF编码方式。这个字符也叫做"bit order mark"。

<USP>表示Unicode中所有的"separator, space(Zs)"分类中的字符,包括:

字符名称你浏览器中的显示
U+0020SPACE
U+00A0NO-BREAK SPACE
U+1680OGHAM SPACE MARK
U+180EMONGoLIAN VOWEL SEPARATOR
U+2000EN QUAD
U+2001EM QUAD
U+2002EN SPACE
U+2003EM SPACE
U+2004THREE-PER-EM SPACE
U+2005FOUR-PER-EM SPACE
U+2006SIX-PER-EM SPACE
U+2007FIGURE SPACE
U+2008PUNCTUATION SPACE
U+2009THIN SPACE
U+200AHaiR SPACE
U+202FNARROW NO-BREAK SPACE
U+205FMEDIUM MATHEMATICAL SPACE
U+3000IDEOGRAPHIC SPACE

注意虽然JS规范承认这些字符可以被用做空白字符,但是除非对源代码的打印、排版有特别的需求,还是应该尽量使用<SP>,尤其是考虑到,相当一批字体无法支持<USP>中的全部字符。

根据一些团队的编码规范,<TAB>常常用于缩进。编程语言中关于用<TAB>还是四个<SP>做缩进的争论从未停止过,此处就不加讨论了。

JS中,WhiteSpace的大部分用途是分隔token和保持代码整齐美观,基本上词法分析器产生的WhiteSpace都会被语法分析器直接丢弃。

所以一些WhiteSpace能够被去掉而完全不影响程序的执行效果。但是也有一些WhiteSpace必须存在的情况,考虑下面代码:

1 .toString();
1.toString(); //报错

上面一段代码中,空白符分隔了1和.,因此它们被理解为两个token。

1.["toString"]();
1 .["toString"](); //报错

相反的情况。

LineTerminator行终结符

这个也是一个非常常见的概念了,JS中只提供了4种字符作为换行符:

LineTerminator ::
    <LF>
    <CR>
    <LS>
    <PS>

其中,<LF>是U+000A,就是最正常换行符,在字符串中的'\n'。

<CR>是U+000D,这个字符真正意义上的"回车",在字符串中是'\r',在一部分windows风格文本编辑器中,换行是两个字符\r\n。

<LS>是U+2028,是Unicode中的行分隔符。

<PS>是U+2029,是Unicode中的段落分隔符。

大部分LineTerminator在被词法分析器扫描出之后,会被语法分析器丢弃,但是换行符会影响JS的两个重要语法特性:自动插入分号和"no line terminator"规则。

考虑下面三段代码:

var a = 1 , b = 1;
a
++
b

按照JS语法的自动插入分号规则,代码解释可能产生歧义。

但是因为后自增运算符有no line terminator的限制,所以实际结果等价于:

var a = 1 , b = 1;
a;
++b;

考虑以下两段代码:

return
    123;
return 123;

因为return有no line terminator的限制,所以第一段代码实际等同于

return;
123;

Comment注释

JS的注释分为单行注释和多行注释两种: 

Comment :: 
    MultiLineComment 
    SingleLineComment

多行注释定义如下:

MultiLineComment :: 
     
MultiLineCommentChars :: 
    MultiLineNotAsteriskChar MultiLineCommentCharsopt 
    * PostAsteriskCommentCharsopt PostAsteriskCommentChars :: 
    MultiLineNotForwardSlashOrAsteriskChar MultiLineCommentCharsopt 
    * PostAsteriskCommentCharsopt MultiLineNotAsteriskChar :: 
    SourceCharacter but not asterisk * 
MultiLineNotForwardSlashOrAsteriskChar :: 
    SourceCharacter but not forward-slash / orasterisk *

这个定义略微有些复杂,实际上这就是我们所熟知的JS多行注释语法的严格描述。

多行注释中允许自由地出现MultiLineNotAsteriskChar ,也就是除了*之外的所有字符。而每一个*之后,不能出现正斜杠符/

单行注释则比较简单:

SingleLineComment ::
    // SingleLineCommentCharsoptSingleLineCommentChars ::
    SingleLineCommentChar SingleLineCommentCharsoptSingleLineCommentChar ::
    SourceCharacter but not LineTerminator

除了四种LineTerminator之外,所有字符都可以作为单行注释。

一般情况下,不论是单行还是多行注释都不会影响程序的意义,但是含有LineTerminator的多行注释会影响到自动插入分号规则:

return123;
return  123;

两者会产生不同的效果。

Token

Token是JS中所有能被引擎理解的最小语义单元。

JS中有4种Token:

Token ::
    IdentifierName 
    Punctuator 
    NumericLiteral 
    StringLiteral

如果不考虑除法和正则的冲突问题,Token还应该包括RegularExpressionLiteral,而Punctuator中也应该添加 / 和 /=两种符号。

IdentifierName

IdentifierName的定义为:

IdentifierName ::
    IdentifierStart
    IdentifierName IdentifierPart
IdentifierStart ::
    UnicodeLetter
    $
    _ 
    \ UnicodeEscapeSequence
IdentifierPart ::
    IdentifierStart
    UnicodeCombiningMark
    UnicodeDigit
    UnicodeConnectorPunctuation
    <ZWNJ>
    <ZWJ>

IdentifierName可以以美元符$下划线_ 或者Unicode字母开始,除了开始字符以外,IdentifierName中还可以使用Unicode中的连接标记、数字、以及连接符号。

IdentifierName的任意字符可以使用JS的Unicode转义写法,使用Unicode转义写法时,没有任何字符限制。

IdentifierName可以是Identifier、NullLiteral、BooleanLiteral或者keyWord,在ObjectLiteral中,IdentifierName还可以被直接当做属性名称使用。

仅当不是保留字的时候,IdentifierName会被解析为Identifier。

 UnicodeLetter, UnicodeCombiningMark, UnicodeDigit, UnicodeConnectorPunctuation各自对应几个Unicode的分类。

JS词法名Unicode分类名code字符数
UnicodeLetterUppercase letterLu1441
Lowercase letterLl1751
Titlecase letterLt31
Modifier letterLm237
Other letterLo11788
Letter numberNl224
UnicodeCombiningMarkNon-spacing markMn1280
Combining spacing markMc353
UnicodeDigitDecimal numberNd460
UnicodeConnectorPunctuationConnector punctuationPc10

注意<ZWNJ>和<ZWJ>是ES5新加入的两个格式控制字符,但是目前为止实测还没有浏览器支持。

JS中的关键字有:

Keyword :: one of
    break do instanceof typeof case else new var catch finally return void continue for switch while debugger function this with default if throw delete in try

还有7个为了未来使用而保留的关键字: 

FutureReservedKeyword :: one of
    class enum extends super const export import

在严格模式下,有一些额外的为未来使用而保留的关键字:

implements let private public interface package protected static yield

除了这些之外,NullLiteral: 

NullLiteral ::
    null

和BooleanLiteral:

BooleanLiteral ::
    true false

也是保留字,不能用于Identifier。

Punctuator

JavaScript使用48个运算符,因为前面提到的除法和正则问题, /和/=两个运算符被拆分为DivPunctuator。其余的运算符为:

 Punctuator :: one of
    { } ( ) [ ] . ; , < > <= >= == != === !== + - * % ++ -- << >> >>> & | ^ ! ~ && || ? : = += -= *= %= <<= >>= >>>= &= |= ^=

所有运算符在语法分析器中作为不同的symbol出现。

NumericLiteral

JS规范中规定的数字直接量可以支持两种写法:十进制和十六进制整数,尽管标准中没有提到,但是大部分JS实现还支持以0开头的八进制整数写法。

所以实际上JS的NumericLiteral产生式应该是这样的:

NumericLiteral :: 
    DecimalLiteral
    HexIntegerLiteral
    OctalIntegerLiteralnot-standard

只有十进制可以表示浮点数,DecimalLiteral 定义如下:

DecimalLiteral ::
    DecimalIntegerLiteral . DecimalDigitsopt ExponentPartopt
    . DecimalDigits ExponentPartopt
    DecimalIntegerLiteral ExponentPartoptDecimalIntegerLiteral ::
    0 
    NonZeroDigit DecimalDigitsoptDecimalDigits ::
    DecimalDigit
    DecimalDigits DecimalDigit
DecimalDigit :: one of
    0 1 2 3 4 5 6 7 8 9
NonZeroDigit:: one of
    1 2 3 4 5 6 7 8 9
ExponentPart::
    ExponentIndicator SignedInteger
ExponentIndicator :: one of
    e E
SignedInteger ::
    DecimalDigits
    + DecimalDigits
    - DecimalDigits

JS中的StringLiteral支持单引号和双引号两种写法。

十进制数的小数点前和小数点后均可以省略, 所以 1. 和 .1 都是合法的数字直接量,特别地,除了0之外,十进制数不能以0开头(这其实是为了八进制整数预留的)。

.同时还是一个Punctuator,在词法分析阶段,.123 应该优先被尝试理解为 NumericLiteral ,而非 Punctuator NumericLiteral。

十六进制整数产生式如下:

HexIntegerLiteral ::
    0x HexDigit
    0X HexDigit
    HexIntegerLiteral HexDigit
HexDigit :: one of
    0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F

JS中支持0x标记的大小写形式,十六进制数字中的大小写也可以任意使用。

八进制整数是非标准的,但是大多数引擎都支持:

OctalIntegerLiteral :: 
    0 OctalDigit
    OctalIntegerLiteral OctalDigit 
OctalDigit :: one of
    0 1 2 3 4 5 6 7

StringLiteral

JS中的StringLiteral支持单引号和双引号两种写法。

StringLiteral ::
    " DoubleStrinGCharactersopt "
    ' SingleStringCharactersopt '

单双引号的区别仅仅在于写法,在双引号字符串直接量中,双引号必须转义,在单引号字符串直接量中,单引号必须转义

DoubleStringCharacters ::
    DoubleStringCharacter DoubleStringCharactersoptSingleStringCharacters ::
    SingleStringCharacter SingleStringCharactersoptDoubleStringCharacter ::
    SourceCharacter but not double-quote " or backslash \ or LineTerminator
    \ EscapeSequence
    LineContinuation
SingleStringCharacter ::
    SourceCharacter but not single-quote ' orbackslash \ or LineTerminator
    \ EscapeSequence
    LineContinuation

字符串中其他必须转义的字符是\和所有换行符。

JS中支持四种转义形式,还有一种虽然标准没有定义,但是大部分实现都支持的八进制转义

EscapeSequence ::
    CharacterEscapeSequence
    0 [lookahead no DecimalDigit]
    HexEscapeSequence
    UnicodeEscapeSequence
    OctalEscapeSequencenot-standard

第一种是单字符转义。 即一个反斜杠\ 后面跟一个字符这种形式。

CharacterEscapeSequence ::
    SingleEscapeCharacter
    NonEscapeCharacter
SingleEscapeCharacter :: one of
    ' " \ b f n r t v
NonEscapeCharacter ::
    SourceCharacter but notEscapeCharacter or LineTerminator

有特别意义的字符包括有SingleEscapeCharacter所定义的9种,见下表:

转义字符转义结果你浏览器中的显示
'U+0022
"
"U+0027
'
\U+005C
\
bU+0008

fU+000C
nU+000A
rU+000D
tU+0009
vU+000B

除了这9种字符、数字、x和u以及所有的换行符之外,其它字符经过\转义都是自身。

十六进制转义只支持两位,也就是说,这种写法只支持ASCII字符:

HexEscapeSequence ::
    x HexDigit HexDigit

Unicode转义可以支持BMP中的所有字符:

UnicodeEscapeSequence ::
    u HexDigit HexDigit HexDigit HexDigit

LineContinuation可以被理解为一种特别的转义。写字符串直接量时灵活使用LineContinuation可以增加可读性。

LineContinuation ::
    \ LineTerminatorSequence
LineTerminatorSequence ::
    <LF>
    <CR> [lookahead no <LF> ]
    <LS>
    <PS>
    <CR>
    <CR> <LF>

为了适应Windows风格的文本,JS把"\r\n"作为一个换行符使用。

注意因为CR在某些windows风格的编辑器中没法显示出来,所以乱用的话会产生奇怪的效果。

RegularExpressionLiteral

正则表达式由Body和Flags两部分组成:

RegularExpressionLiteral ::
    / RegularExpressionBody / RegularExpressionFlags

其中Body部分至少有一个字符,第一个字符不能是*(因为结束的注释

┣WhiteSpace空白起到分隔或者保持美观作用的空白字符
┣Token词法标记一切JS中有实际意义的词法标记
┃┣IdentifierName标识名称以字母或_或$开始的一个单词,可以用于属性名
┃┃┣Identifier标识符非保留字的IdentifierName,可以用于变量名或者属性名
abc
┃┃┣Keyword关键字有特殊语法意义的IdentifierName
while
┃┃┣NullLiteralNull直接量表示一个Null类型的值
null
┃┃┗BooleanLiteral布尔直接量表示一个Boolean类型的值
true
┃┣Punctuator标点符号表示特殊意义的标点符号
*
┃┣NumericLiteral数字直接量表示一个Number类型的值
.12e-10
┃┣StringLiteral字符串直接量表示一个String类型的值
"Hello world!"
┃┗RegularExpressionLiteral正则表达式直接量表示一个RegularExpression类的对象
/[a-z]+$$/g
┗LineTerminator行终结符起到分隔或者保持美观作用的换行字符,可能会影响自动插入分号

附表 所有JS词法中的不可见字符

简写字符概述
<TAB>U+0009tab符,用于空白
<VT>U+000B竖向tab符,用于空白
<FF>U+000C换页,用于空白
<SP>U+0020空格,用于空白
<NBSP>U+00A0非断行空格,用于空白
<BOM>U+FEFF零宽非断行空格,字节序标记,用于空白
<ZWNJ>U+200C零宽非连接符,用于标识符
<ZWJ>U+200D零宽连接符,用于标识符
<LF>U+000A换行,用于行终结符
<CR>U+000D回车,用于行终结符
<LS>U+2028行分隔符,用于行终结符
<PS>U+2029页分隔符,用于行终结符

关于JavaScript词法都有哪些就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

--结束END--

本文标题: JavaScript词法都有哪些

本文链接: https://lsjlt.com/news/82389.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • JavaScript词法都有哪些
    这篇文章将为大家详细讲解有关JavaScript词法都有哪些,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。InputElement 输入元素输入元素是JS词...
    99+
    2024-04-02
  • javascript词法关键字有哪些
    这篇文章主要讲解了“javascript词法关键字有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“javascript词法关键字有哪些”吧!javascript是一种解释型语言。 语言其...
    99+
    2023-06-04
  • javascript注释都有哪些
    javascript中的注释有:1.单行注释,以"//"开头;2.多行注释,以 结尾;javascript中的注释有以下两种单行注释javascript中单行注释一般以"//"开头,到改行的末尾结束。//这是一行注释,只能注释单行。//另...
    99+
    2024-04-02
  • JavaScript中set集合的方法都有哪些
    JavaScript中set集合的方法都有哪些,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。set方法有:1、add(),用于往集合添加元...
    99+
    2024-04-02
  • javascript都有哪些事件类型
    本篇内容介绍了“javascript都有哪些事件类型”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! ...
    99+
    2024-04-02
  • JavaScript优化技巧都有哪些
    JavaScript优化技巧都有哪些,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。作为开发人员,我们一直在寻找让我们的代码更快更好的方法。但在...
    99+
    2024-04-02
  • JavaScript优化技术都有哪些
    本篇文章为大家展示了JavaScript优化技术都有哪些,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。开发人员的生活总是在学习新事物,并且跟上变化的难度不应该比现在...
    99+
    2024-04-02
  • JavaScript数据类型都有哪些
    这篇文章将为大家详细讲解有关JavaScript数据类型都有哪些,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。1、基本JavaScript数据类型在Java...
    99+
    2024-04-02
  • javascript正则函数都有哪些
    javascript中的正则函数有:1.test,检测一个字符串是否匹配某个模式;2.match,在字符串内检索指定的值;3.replace,在字符串中替换字符;4.search,检索字符串中指定的子字符串;javascript中的正则函数...
    99+
    2024-04-02
  • javascript中的函数都有哪些
    本篇内容主要讲解“javascript中的函数都有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“javascript中的函数都有哪些”吧!按字母排序:abs acos action aler...
    99+
    2023-06-03
  • canvas方法都有哪些
    canvas常见的方法有getContext()、fillRect()、strokeRect()、clearRect()、beginPath()、moveTo()、lineTo()、arc()、fill()、stroke()、save()、...
    99+
    2023-08-17
  • javascript都有哪些基本数据类型
    本篇内容主要讲解“javascript都有哪些基本数据类型”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“javascript都有哪些基本数据类型”吧! ...
    99+
    2024-04-02
  • JavaScript数组精简技巧都有哪些
    今天就跟大家聊聊有关JavaScript数组精简技巧都有哪些,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。数组是 JS 很常见的一种数据结构,咱们在...
    99+
    2024-04-02
  • GitHub上JavaScript开源项目都有哪些
    今天就跟大家聊聊有关GitHub上JavaScript开源项目都有哪些,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1. javascript-al...
    99+
    2024-04-02
  • Python程序员都应该知道的缩写词有哪些
    这篇文章主要讲解了“Python程序员都应该知道的缩写词有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python程序员都应该知道的缩写词有哪些”吧!1. OOP(面向对象编程)要介绍...
    99+
    2023-06-16
  • ORDER BY的用法都有哪些
    今天就跟大家聊聊有关ORDER BY的用法都有哪些,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。小伙伴们在进行SQL排序时,都能很自然的使用到ORD...
    99+
    2024-04-02
  • 2020年优秀JavaScript框架都有哪些呢
    2020年优秀JavaScript框架都有哪些呢,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。2020比较热门的Javascr...
    99+
    2024-04-02
  • php中魔术方法都有哪些
    本教程操作环境:windows7系统、PHP7.1版、DELL G3电脑在面向对象编程中,PHP 提供了一系列的魔术方法,这些魔术方法为编程提供了很多便利,在 PHP 中的作用是非常重要的。PHP 中的魔术方法通常以__(两个下划线)开始,...
    99+
    2021-12-03
    php 魔术方法
  • 301重定向都有哪些方法
    301重定向的方法有:IIS下301设置Internet信息服务管理器 → 虚拟目录 → 重定向到URL,输入需要转向的目标URL,并选择“资源的永久重定向”。ASP下的301重定向代码<%@ Language=VBScri...
    99+
    2024-04-02
  • Python中都有哪些排序算法
    今天就跟大家聊聊有关Python中都有哪些排序算法,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1.冒泡排序冒泡排序是 CS  入门课程中最常讲授的一种,因为它清楚地说明了...
    99+
    2023-06-16
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作