Coder Social home page Coder Social logo

microsoft / powerquery-parser Goto Github PK

View Code? Open in Web Editor NEW
104.0 15.0 23.0 3.71 MB

A parser for the Power Query / M formula language, written in TypeScript

License: MIT License

TypeScript 99.52% JavaScript 0.48%
parser typescript microsoft opensource powerquery m

powerquery-parser's Introduction

powerquery-parser

Build Status

A parser for the Power Query/M language, written in TypeScript. Designed to be consumed by other projects.

How to use

The most common way to consume the project is to interact with the helper functions found in taskUtils.ts. There are all-in-one functions, such as tryLexParse, which does a full pass on a given document. There are also incremental functions, such as tryLex and tryParse, which perform one step at a time. Minimal code samples can be found in example.ts.

Related projects

Things to note

Parser

The parser started off as a naive recursive descent parser with limited backtracking. It mostly followed the official specification released in October 2016. Deviations from the specification should be marked down in specification.md. A combinatorial parser has since been added which uses the naive parser as its base.

Style

This project uses prettier as the primary source of style enforcement. Additional style requirements are located in style.md.

How to build

  • Install NodeJS
  • npm install
  • npm run-script build

How to run tests

  • Install NodeJS
  • npm install
  • npm test

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.

When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

powerquery-parser's People

Contributors

bgribaudo avatar csigs avatar dependabot[bot] avatar jordanboltonmn avatar mattmasson avatar microsoft-github-policy-service[bot] avatar microsoftopensource avatar msftgits avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

powerquery-parser's Issues

Improve API for moving from TriedParse to TriedInspect

It would be nice if we could easily go from a TriedParse to a TriedInspect. We currently have to check the parse results and take either TriedParse.value or TriedParse.error.context. I had to create an intermediate Inspectable interface to unify the code paths.

Most intellisense operations that require Inspect won't care whether the parse succeeded without errors.

interface Inspectable {
    nodeIdMapCollection: PQP.NodeIdMap.Collection;
    leafNodeIds: ReadonlyArray<number>;
}

const triedParser: PQP.Parser.TriedParse = PQP.Parser.tryParse(triedSnapshot.value);
let inspectableParser: Inspectable | undefined;
if (triedParser.kind === PQP.ResultKind.Ok) {
    inspectableParser = triedParser.value;
} else if (triedParser.error instanceof PQP.ParserError.ParserError) {
    inspectableParser = triedParser.error.context;
}

[BUG] Sequences using variables causes a parse error

Expected behavior
Valid queries should not raise a a parse error. It runs as expected in Power BI.

Actual behavior

Expected to find a right brace <'}'>, but a keyword <'in'> was found insteadpowerquery(Error.Parse)

image

To Reproduce: Case 1

let
    start = 0, 
    end = 10,
    sequence = {start..end}
in
    sequence

Expected to find a right brace <'}'>, but a keyword <'in'> was found insteadpowerquery(Error.Parse)

To Reproduce: Case 2

let
    start = 10,
    Numbers = {start..10}
in 
    Numbers

Expected to find a right brace <'}'>, but a numeric literal was found insteadpowerquery(Error.Parse)

Working case

let
    end = 10,
    Numbers = {0..end}
in 
    Numbers

[Enhancement] Is there a python version of the parser?

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

We are using python, and would love to be able to have a python power query parser.

Describe the solution you'd like
A clear and concise description of what you want to happen.
A python power query parser.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

[Enhancement] Remove LexerSnapshot

Is your feature request related to a problem? Please describe.
LexerSnapshot existed due to old reasons which no longer apply. It doesn't have any real reason to exist anymore.

Describe the solution you'd like
Update the parser to take a lexer state and read tokens directly from there.

Describe alternatives you've considered
N/A

Additional context
N/A

IntelliSense Support

Am I correctly getting the sense that there are plans to extend this library to provide support for code editor IntelliSense uses? :-)

/ Related #60

Ben

[BUG] - Recursive Section Member Reference Isn't Accepted as Valid

Expected behavior
The M language specification and the existing Power Query SDK allow a section member to use an exclusive identifier reference to refer to itself (e.g. the SumConsecutive(x - 1) reference in the below example).

section SomeSection;

SumConsecutive = (x) => if x <= 0 then 0 else x + SumConsecutive(x - 1);

Actual behavior
The parser considers the above-mentioned reference an error, complaining that it "cannot find the name 'SumConsecutive'".
image

To Reproduce
In VSCode, create a new Power Query document. Paste in the above M code. The error shown in the screenshot will then be displayed.

Additional context
Power Query / M Language extension version: v0.1.42

Thank you for your help with this, and for the VSCode extension!

#nan inside of if then clause results in parser error

if [str] = "nan" then
    #nan
else if [str] = "+inf" then
    #infinity
else if [str] = "-inf" then
    -#infinity
else
    Double.From([str], "en-us")

Expected to find one of the following on line 2, column 5, but a KeywordHashNan was found instead: [HexLiteral,KeywordFalse,KeywordTrue,NumericLiteral,NullLiteral,StringLiteral].

Inspect - don't include current section member while inside of a let

Unit test could be:

it(`section foo; x = 1; y = let a = 1, b = |2 in b;`, () => {
    const [text, position] = textWithPosition(
        `section foo; x = 1; y = let a = 1, b = |2 in b;`,
    );
    const expected: AbridgedInspection = {
        nodes: [],
        scope: [`a`, `x`],
    };
    expectParseOkAbridgedInspectionEqual(text, position, expected);
});

Currently, y is included in the scope.
Alternatively, we could include y, but also provide a property to call out that that is the member we're currently on.

[Enhancement] Compressed code formatting

It would be great to have an option for compressed code formatting.

Especially the line breaks for the value pairs for automatically generated code like in "Table.TransformColumnTypes" or "Table.RenameColumns" (after the Table.PromoteHeaders) make the code very lengthy.

image

[Enhancement] Reason tag for CancellationToken

Is your feature request related to a problem? Please describe.
It's unclear why a cancellation has occured.

Describe the solution you'd like
A reason attribute under ICancellationToken

Describe alternatives you've considered
N/A

Additional context
N/A

#infinity parser error

if [str] = "nan" then
    #nan
else if [str] = "+inf" then
    **#infinity**
else if [str] = "-inf" then
    -#infinity
else
    Double.From([str], "en-us")]

results in:

{
	"resource": "Untitled-1",
	"owner": "_generated_diagnostic_collection_name_#0",
	"severity": 8,
	"message": "Expected to find one of the following, but a keyword <'#infinity'> was found instead: hex literal, keyword <'false'>, keyword <'#nan'>, keyword <'true'>, numeric literal, <'null'>, string",
	"startLineNumber": 4,
	"startColumn": 5,
	"endLineNumber": 4,
	"endColumn": 14
}

Comments in Ast

Is there a reason why the comments are not part of the parsed Ast but just flattened in the lexer snapshot? I'm building a m language autoformatter that uses your parser but at the moment I throw away all comments because it's very hard to remap the flattened comments to the Ast nodes. I think making the comments part of the ast would be the straightforward solution.

Inspect - provide list of valid/expected keywords for position

I've recently added M keywords to intellisense suggestions. It would be great if the inspection class returned a list of expected keywords for the current position.

ex. shared a = |

should include keywords like let and if, but not else or otherwise ...

Lexer.updateRange() with matching start/end ranges should insert text rather than replace

To match the LSP interface, calling updateRange where the start and end ranges are the same should be treated as an insert.

The current test case in Lexer.updateRange should come out to Xfoobar instead of Xoobar.

        it(`foobar -> Xoobar`, () => {
            const range: Lexer.Range = {
                start: {
                    lineNumber: 0,
                    lineCodeUnit: 0,
                },
                end: {
                    lineNumber: 0,
                    lineCodeUnit: 0,
                },
            };
            const state: Lexer.State = expectLexerUpdateRangeOk(
                `foobar`,
                "X",
                range
            );
            expect(state.lines.length).to.equal(1);
            expect(state.lines[0].text).to.equal("Xoobar");
        });

[BUG] Parser error on record type definition - Did you leave a dangling comma?

section Connector;

[DataSource.Kind="Test", Publish="Test.Publish"]
shared Test.Contents = Value.ReplaceType(TestImpl, TestType);

TestType = type function (
        param as (type text meta [
            Documentation.FieldCaption = "Param"
        ]),
        optional options as (type nullable [])
    ) as table meta [
        Documentation.Name = "Test Connector"
    ];

 TestImpl = (param as text) as table => ...;

Parser syntax error at [10,44] - the open bracket in (type nullable [])

[10, 44] Did you leave a dangling comma?

image

I feel like this might be an actual error, but it doesn't seem to cause an error in Power Query / Visual Studio.

[BUG] escaped quote inside of quoted identifier

Expected behavior
No parser error.

Actual behavior
Parser error.

{
	"resource": "Untitled-1",
	"owner": "_generated_diagnostic_collection_name_#0",
	"code": "Error.Parse",
	"severity": 8,
	"message": "Expected to find a generalized identifier",
	"source": "powerquery",
	"startLineNumber": 1,
	"startColumn": 20,
	"endLineNumber": 1,
	"endColumn": 21
}

To Reproduce

[a = "Test1", b = 5, #"c""" = #duration(1, 0, 0, 0)]

Additional context
Add any other context about the problem here.

C# Interop

Hello,

I'm currently parsing M using Antlr4. Replacing this with a parser backed by Microsoft is very, very interesting to consider. However, my application is written in C#/.Net Core while this project is TypeScript/JavaScript-based.

I'm curious if there are others out there who have set up JS<->C# interop with this parser, and, if so, what technique you found worked well for doing this (e.g. using something like Jint, spinning up a local Node.js web server. etc.). I would be most grateful for any tips you might want to share.

Thank you,
Ben

Trailing . removed from token

Input text:

Access.

When I retrieve the lexer state, I'd expect a single token containing Access., but it looks like the trailing . is removed. The resulting LineTokens are equal to:

[{
    "kind": "Identifier",
    "positionStart": 0,
    "positionEnd": 6,
    "data": "Access"
}]

comma before in should return error at the comma, not the in

statement: let a = 1, in a

Error via M engine is reported as A comma cannot precede an In, with the error range set to the comma.

powerquery-parser message is:

Expected to find a Identifier on line 1, column 12, but a KeywordIn was found instead.

[BUG] Invalid Syntax Accepted for Generalized Identifiers

Expected behavior
generalized-identifiers of "a{new line character}b" and "a/hi/b" should be rejected because they don't comply with the appropriate syntax rules in the Power Query language specification.

Actual behavior
Both of the above identifiers are accepted as valid.

To Reproduce

const customParser: IParser<IParserState> = {
    ...RecursiveDescentParser,
    read: RecursiveDescentParser.readGeneralizedIdentifier,
};
const customSettings: Settings = {
    ...DefaultSettings,
    parser: customParser,
};
const triedLexParse: Task.TriedLexParse = Task.tryLexParse(
    customSettings,
    `a
b`
    // or 'a/*hi*/b'
); // expect the result to be an error; currently, an ok result is being returned

Additional context
If I'm understanding the language specification correctly, a generalized-identifier is made up of one or more (keyword-or-identifier or decimal-digit + keyword-or-identifier) segments, separated by dots (.) or blanks (e.g. spaces).

In turn, the only characters allowed in keyword-or-identifier are letters, numbers and underscores plus connecting, combining and formatting characters. Turning this list into a regular expression (using the specific character classes listed in the spec) produces the following: [\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo}\p{Nl}\p{Mn}\p{Mc}\p{Pc}\p{Cf}\p{Nd}_]

\n, / and * all do not match this regex so I believe should be rejected as invalid generalized-identifier syntax.

(Note: The above regex tests valid characters allowed in a keyword-or-identifier; however, for simplicity, it does not check whether the identifier's starting character matches the rules for the starting character given in the spec.

Inspect - identify when position is left hand side of assignment

We shouldn't return intellisense suggestions when we're on the left hand side of an assignment (i.e. providing a variable name). Ex:

let a = 1, |
let a = 1, bin|

Ideally, the inspection result would provide a boolean flag that the intellisense code would use to determine that no suggestions should be returned in these cases.

Support for localized parser/lexer error messages

To be able to consume this library in PQ clients, we'll need to support full localization of the error messages raised by the parser/lexer.

We should probably review the format of the messages before we submit for localization.

Scoping to Specific Language Components

Hello,

Is there an easy way to scope lexing/parsing so that it is performed relative to a specific language component? In other words, when passing in a string for lexing/parsing, is there an easy way to say "this should be x" (where x might be a regular-identifier, a quoted-identifier, an expression-document, a section-document, etc.) and then have the lexer/parser only consider the input valid if it complies with the expected syntax for x?

So, for example, if section A; shared Query1 = true; is lexed/parsed as an expression-document, the result should be an error because the input, while valid M code, is not an expression-document.

Thank you,
Ben

[Enhancement] New language keyword `catch`

The parser needs to handle the new catch keyword. The new grammar requires a function, but allows 0 or 1 parameters.

= try {0..1}{-1} catch () => "Invalid Range" // return: type text
= try {0..1}{-1} catch () => TextEncoding.Utf16 // return: type number
= try {0..1}{-1} catch (e) => TextEncoding.Utf16 // return: type number
= try {0..1}{-1} catch (e) => e // return: type record

image

image

If you return the parameter, then the first is basically equivalent to the 2nd

= try {0..1}{-1} catch (e) => e
= (try {0..1}{-1})[Error]

I tried to using the each expression, but I wasn't able to.

[Enhancement] Add Parser Support for Invalid Syntax Literals

Describe the solution you'd like
Power Query expressions can contain "invalid syntax literals" (unsure the official name), a syntax construct in the form of #!" … " which is not mentioned in the official language specification.

To enable this parser to fully parse the section documents created by Microsoft Excel and Power BI, both of which can output invalid syntax literals, would it make sense to extend the parser to support these literals?

Example (pulled verbatim from a Power BI file):

section Section1;

shared Query1 = let
    Source = #!"let a"
in
    Source;

Additional context
For more details on these literals, see MicrosoftDocs/powerquery-docs#12.

field-specification Deviation Double-Check

Hello,

In https://github.com/microsoft/powerquery-parser/blob/master/specification.md, the following deviation from the M language spec is mentioned:

  • The field-specification construct requires an identifier. Instead identifer is replaced with generalized-identifier.

The spec currently contains the following grammar definitions:

field-specification:
      optional(opt) field-name field-type-specification(opt)

field-name:
      generalized-identifier
      quoted-identifier

With the way field-name currently is defined, is the above-quoted bullet a legacy relic that can be removed?

Ben

Missed syntax error for trailing commas in record declaration

Connector = [
    TestConnection = (dataSourcePath) => { "Foo.Contents", dataSourcePath },
    Authentication = [
        AuthRecord = [
            AuthorizationUri = (resource) => FunctionCall(),
        ],
    ]
];

should report syntax errors for trailing , after AuthorizationUri line, and AuthRecord declaration.

Inspect - don't exclude valid scope members declared after cursor position

I'm not sure why we are filtering out members that are declared after the current position, since they would still be valid identifier suggestions (unless I am misunderstanding the intended use of the scope member).

Unit test:

it(`section foo; a = 1; b = |2; c = 1;`, () => {
    const [text, position] = textWithPosition(`section foo; a = 1; b = |2; c = 1;`);
    const expected: AbridgedInspection = {
        nodes: [],
        scope: [`a`, `c`],
    };
    expectParseOkAbridgedInspectionEqual(text, position, expected);
});

Multi Sections, SectionAccessExpression parser error

I just tried to parse some examples from the power query section specification and it appears they cannot be parsed.

Expected behavior
As sections are not excluded in specifications.md it would appear that they are supported

Actual behavior
For example this code

section Section1; 
A = "Hello";      
B = A + " world";  
K = Section1!A + 2;

results in an Error: ."Error: Expected to find a semicolon <';'>, but a exclamation mark <'!'> was found instead
It only works without the section access expression.

Also this code

section Section1; 
A = "Hello";      

section Section2;
B = "HELLO";

results in error "Expected to find a identifier, but a keyword <'section'> was found instead". Only one section works, multiple sections result in this error.

To Reproduce
I took the above code examples and ran the formatter with:

import { Task, DefaultSettings, ResultKind, Ast } from '@microsoft/powerquery-parser';
let parsed = Task.tryLexParse(DefaultSettings, code);

Additional context
I use Version 0.1.50-5, I tried to pull the latest version but there I cannot parse any document. Just in case you're also interested in that error:

TypeError: Cannot read property 'tryRead' of undefined
    at tryParse (dir\node_modules\@microsoft\powerquery-parser\lib\task.js:25:34)
    at Object.tryLexParse (dir\node_modules\@microsoft\powerquery-parser\lib\task.js:97:24)
    at Object.<anonymous> (dir\src\formatter.ts:60:21)
    at Generator.next (<anonymous>)
    at dir\node_modules\tslib\tslib.js:110:75
    at new Promise (<anonymous>)
    at Object.__awaiter (dir\node_modules\tslib\tslib.js:106:16)
    at Object.format (dir\dist\formatter.js:49:20)
    at Object.<anonymous> (dir\src\test\debug.ts:22:1)
    at Module._compile (internal/modules/cjs/loader.js:1155:14)

Parser error for column names with .

let
    t = #table({"Column.1"}, {}),
    a = Table.AddColumn(t, "Addition", each [Timestamp.1] + 1, type number)
in
    a

Results in parser error:

Expected to find a RightBracket on line 3, column 55, but a NumericLiteral was found instead.

[BUG] Inconsistent parsing of identifiers with PowerBI

A user of our powerquery formatter service just brought iconsistent behavior to our attention. The relevant issue in our repo is here.

Expected behavior
Consistent parsing behavior of identifiers of powerquery-parser and the internal m-parser of PowerBI

Actual behavior
PowerBI will allow parsing of identifiers such as MyIdentifier.1 while this library fails. Looking at the powerquery language spec

identifier:
      regular-identifier
      quoted-identifier
regular-identifier:
      available-identifier
      available-identifier dot-character regular-identifier
available-identifier:
      A keyword-or-identifier that is not a keyword
keyword-or-identifier:
      letter-character
      underscore-character
      identifier-start-character identifier-part-characters
identifier-start-character:
      letter-character
      underscore-character
identifier-part-characters:
      identifier-part-character identifier-part-charactersopt
identifier-part-character:
      letter-character
      decimal-digit-character
      underscore-character
      connecting-character
      combining-character
      formatting-character

the Identifier MyIdentifier.1 is actually an invalid identifier. So your library is consistent with the spec but power bi isn't. This isn't really a critical bug but I still wanted to file it with you in case you want to address it. I filed it with you instead of over at the powerbi forum because it will just get buried over there.

To Reproduce
Please include the following:

  • (Required) The Power Query script that triggers the issue.
    let MyIdentifier.1 in MyIdentifier.1
  • (Required) Any non-default settings used in the API call(s) which trigger the issue.
    none
  • (Ideally) A minimal reproducible example. Can you reproduce the problem by calling a function in src/example.ts?

Additional context
Add any other context about the problem here.

[BUG] maybeNormalizeNumber doesn't work on hex literals

Expected behavior
maybeNormalizeNumber("0xdeadbeef") returns a normalized hex

Actual behavior
maybeNormalizeNumber("0xdeadbeef") returns undefined

To Reproduce
maybeNormalizeNumber("0xdeadbeef")

Additional context
N/A

Parser error when function return type is nullable

I recently got a bug report for my powerquery formatter which I tracked down to occur in the parser library. You can have a look at the original issue here.
The minimal code to reproduce the issue is:

let
    Fn = () as nullable text => "asd"
in
    Fn

Everything works fine if the function return type is not specified nullable. But with the nullable key word an exception is thrown by the parser:

Error: InvariantError: cannot delete Ast if it has children - {
    "nodeId": 8,
    "childIds": [
        10
    ]
}

Stack:

 at new CommonError (.\node_modules\@microsoft\powerquery-parser\lib\common\error.js:23:28)
    at Object.ensureCommonError (.\node_modules\@microsoft\powerquery-parser\lib\common\error.js:84:16)
    at Object.tryRead (.\node_modules\@microsoft\powerquery-parser\lib\parser\IParser\IParserUtils.js:19:51)
    at tryParse (.\node_modules\@microsoft\powerquery-parser\lib\task.js:37:34)
    at Object.tryLexParse (.\node_modules\@microsoft\powerquery-parser\lib\task.js:74:22)
    at Object. (.\dist\formatter.js:47:47)
    at Generator.next ()
    at .\node_modules\tslib\tslib.js:114:75
    at new Promise ()
    at Object.__awaiter (.\node_modules\tslib\tslib.js:110:16)

I could not find anything in the powerquery function documentation or the consolidated grammar that would indicate that nullable return types are prohibited for functions.

Identifier not parsed with unicode symbols [BUG]

I just god a bug report from a user of powerqueryformatter.com . He appears to be using chinese unicode symbols as identifiers and the parser throws when encountering the symbol.

Expected behavior
The query he is trying to format is:
let 零 = 1 in 零
The spec says an identifier consists of letter_character which itself is defined as

letter-character:
      A Unicode character of classes Lu, Ll, Lt, Lm, Lo, or Nl

I checked the symbol 零 (I don't know what it means btw) with a unicode analyzer and it says it is of category Lo which should be a valid letter-character. I checked in Excel and PowerbBI and the query is parsed without problems.

Actual behavior
Parser throws error

To Reproduce
Please include the following:

  • (Required) The Power Query script that triggers the issue.
    *let 零 = 1 in 零
  • (Required) Any non-default settings used in the API call(s) which trigger the issue.
    none
  • (Ideally) A minimal reproducible example. Can you reproduce the problem by calling a function in src/example.ts?

Additional context
Add any other context about the problem here.

Inspect - unexpected positionArgumentIndex

positionArgumentIndex is equal to 0 - I'd expect it to be equal to 1.

Unit test:

it(`foo(x,|)`, () => {
    const [text, position] = textWithPosition(`foo(x,|)`);
    const expected: AbridgedInspection = {
        nodes: [
            {
                kind: NodeKind.InvokeExpression,
                maybePositionStart: {
                    codeUnit: 3,
                    lineCodeUnit: 3,
                    lineNumber: 0,
                },
                maybeName: "foo",
                maybePositionEnd: undefined,
                maybeArguments: {
                    numArguments: 2,
                    positionArgumentIndex: 1,
                },
            },
        ],
        scope: [`x`, `foo`],
    };
    expectParseErrAbridgedInspectionEqual(text, position, expected);
});

[Enhancement] Add SectionAccessExpression

Is your feature request related to a problem? Please describe.
SectionAccessExpression isn't supported.

Describe the solution you'd like
Support SectionAccessExpression.

Describe alternatives you've considered
N/A

Additional context
N/A

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.