Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dart 2.0 Support #24

Open
wants to merge 65 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
4d6bb84
🚧wip (repo) fix type casting
devkabiir Apr 17, 2019
4395814
🚚mv (option) seperate option from main library
devkabiir Apr 23, 2019
2f4c357
🔥prune (parser) Replace `Undefined` by `??` operator
devkabiir Apr 23, 2019
9b6a7c2
🐛fix (parser) type casting in `manyUntil`
devkabiir Apr 23, 2019
d36487c
🎨style (repo) Run `dartfmt -w . --fix`
devkabiir Apr 23, 2019
2540e25
🐛fix (option) Make visible for external use
devkabiir Apr 23, 2019
889e0d0
♻️refactor (parser) Use public method `run` instead of `_run`
devkabiir Apr 23, 2019
7493b5b
🚨lint (parser) fix `prefer_final_locals`
devkabiir Apr 23, 2019
70a2797
🚨lint (repo) fix `prefer_single_quotes`
devkabiir Apr 23, 2019
5a8be37
🔧conf (analysis) add lints
devkabiir Apr 23, 2019
c646e89
🚨lint (parser) fix `prefer_const_declarations`
devkabiir Apr 23, 2019
d65b2aa
🚨lint (parser) fix `prefer_is_empty`
devkabiir Apr 23, 2019
adc63a6
🚨lint (parser) fix `unnecessary_cast`
devkabiir Apr 23, 2019
db6d426
🚨lint (repo) fix `use_function_type_syntax_for_parameters`
devkabiir Apr 23, 2019
f2de88c
🚨lint (parser) fix `avoid_types_on_closure_parameters`
devkabiir Apr 23, 2019
0e1c5ff
🚨lint (parser) ignore `parameter_assignments`
devkabiir Apr 23, 2019
586a306
🚨lint (parser) ignore `avoid_types_on_closure_parameters`
devkabiir Apr 23, 2019
a461700
🚨lint (accumulators) ignore `avoid_types_on_closure_parameters`
devkabiir Apr 23, 2019
cbf53ad
🐛fix (parser) Type casting in `chainr1`
devkabiir Apr 23, 2019
ea27437
🔧conf (pubspec) Update sdk constraint
devkabiir Apr 23, 2019
e036baa
🔥prune (option) Unused code
devkabiir Apr 23, 2019
8a2ea17
🐛fix (operator) dart operator test
devkabiir Apr 23, 2019
3758e9c
♻️refactor (parser) Replace `|` operator with `or` method
devkabiir Apr 23, 2019
acd26c5
♻️refactor (parser) Replace `+` operator with `and` method
devkabiir Apr 23, 2019
08a1c8c
♻️refactor (parser) Replace `*` operator with `apply`
devkabiir Apr 23, 2019
6ff17c7
♻️refactor (parser) Replace `>` operator with `thenKeep` method
devkabiir Apr 23, 2019
03ea10b
fixup! ♻️refactor (parser) Replace `*` operator with `apply`
devkabiir Apr 23, 2019
859715a
fixup! ♻️refactor (parser) Replace `+` operator with `and` method
devkabiir Apr 23, 2019
4efbda7
fixup! ♻️refactor (parser) Replace `|` operator with `or` method
devkabiir Apr 23, 2019
264fc9f
♻️refactor (parser) Replace `<` operator with `thenDrop`
devkabiir Apr 23, 2019
466e089
♻️refactor (parser) Disable `^` operator
devkabiir Apr 23, 2019
a59fc29
♻️refactor (parser) Disable `>>` operator
devkabiir Apr 23, 2019
2dc865a
♻️refactor (accumulators) Disable `+` and `^` operators
devkabiir Apr 23, 2019
772fbef
♻️refactor (parser-test) Use `thenKeep` instead of `>`
devkabiir Apr 23, 2019
e3c9a67
♻️refactor (parser-test) Use `apply` instead of `*`
devkabiir Apr 23, 2019
482f8c2
fixup! ♻️refactor (parser-test) Use `thenKeep` instead of `>`
devkabiir Apr 23, 2019
f0a1dc3
♻️refactor (parser-test) Use `map` instead of `^`
devkabiir Apr 23, 2019
0d471a9
♻️refactor (parser-test) Use `and` instead of `+`
devkabiir Apr 23, 2019
4dd656c
♻️refactor (parser-test) Use `or` instead of `|`
devkabiir Apr 23, 2019
381557c
♻️refactor (parser-model) Use `or` instead of `|`
devkabiir Apr 23, 2019
8aa970f
♻️refactor (parser-model) Use `apply` instead of `*`
devkabiir Apr 23, 2019
f1ce132
♻️refactor (parser-model) Use `then` instead of `>>`
devkabiir Apr 23, 2019
296cadd
♻️refactor (parser-model) Use `thenKeep` instead of `>`
devkabiir Apr 23, 2019
bea3c53
fixup! ♻️refactor (parser-test) Use `or` instead of `|`
devkabiir Apr 23, 2019
f488d1c
♻️refactor (parser) Loosen type requirement for `_concat`
devkabiir Apr 23, 2019
32a8598
♻️refactor (parser) Switch to static method instead of factory constr…
devkabiir Apr 24, 2019
2e6ec50
♻️refactor (parser) Use the new static methods instead of factory con…
devkabiir Apr 24, 2019
c9a1f8d
♻️refactor (parser) Properly cast types using `cast` instead of `as` …
devkabiir Apr 24, 2019
f35bccf
💡docs (parser) Use triple slashes for `apply` method
devkabiir Apr 24, 2019
b428709
♻️refactor (parser-model) Fix minor type castings
devkabiir Apr 24, 2019
72e5d10
🔧conf (analysis) Disable `avoid_positional_boolean_parameters`
devkabiir Apr 24, 2019
76109ad
📌dep (pubspec) Pin `test` to `^1.0.0`
devkabiir Apr 24, 2019
1daad6a
👥contrib (pubspec) Add Dinesh Ahuja
devkabiir Apr 24, 2019
dcfc4d8
🔖release (package) Bump version to `2.0.0`
devkabiir Apr 24, 2019
d03946b
📝docs (CHANGELOG) Add notes for 2.0.0
devkabiir Apr 24, 2019
49d40f4
fixup! 📝docs (CHANGELOG) Add notes for 2.0.0
devkabiir Apr 24, 2019
2bd4dd0
👥contrib (parser) Add Dinesh Ahuja
devkabiir Apr 24, 2019
d4dd398
👥contrib (parser-test) Add Dinesh Ahuja
devkabiir Apr 24, 2019
1b91cea
Revert "🐛fix (operator) dart operator test"
devkabiir Apr 24, 2019
135ed79
♻️refactor (parser) Re-enable all operators
devkabiir Apr 24, 2019
ab3cdfb
♻️refactor (accumulators) Re-enable all operators
devkabiir Apr 24, 2019
7ba818d
♻️refactor (example) Fix `full_arith` example
devkabiir Apr 24, 2019
f7d0370
♻️refactor (example) Make `full_arith` type safe
devkabiir Apr 25, 2019
3d6dcac
♻️refactor (parser-test) Fix depricated usage of `throws`
devkabiir Apr 25, 2019
69d1b33
🔥prune (parser) Remove redundant castings
devkabiir Apr 25, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ doc/gen
doc/tutorial/bin/packages
.idea/
.packages
.dart_tool
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Parsers Changelog

## 2.0.0

- Dart 2.0 compatible
- Operators disabled for now, so instead of `parser1 | parser2` use `parser1.or(parser2)`
- `%` operator is an exception as it does not require any type parameters
- Examples in `example` directory still don't work.

## 1.0.0

- Make strong mode and dart 2 compatible.
Expand Down
34 changes: 33 additions & 1 deletion analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,34 @@
analyzer:
strong-mode: true
strong-mode:
implicit-casts: false
implicit-dynamic: true

linter:
rules:
# - avoid_positional_boolean_parameters
- avoid_types_on_closure_parameters
- avoid_unused_constructor_parameters
- directives_ordering
- file_names
# - flutter_style_todos
- parameter_assignments
- prefer_adjacent_string_concatenation
- prefer_asserts_in_initializer_lists
- prefer_const_declarations
- prefer_final_fields
- prefer_final_locals
# - prefer_for_elements_to_map_fromIterable # not yet landed in stable
- prefer_generic_function_type_aliases
# - prefer_if_elements_to_conditional_expressions # not yet landed in stable
- prefer_is_empty
- prefer_single_quotes
# - prefer_spread_collections # not yet landed in stable
- prefer_typing_uninitialized_variables
- recursive_getters
- unnecessary_await_in_return
- unnecessary_lambdas
- unnecessary_const
- unnecessary_new
- use_function_type_syntax_for_parameters
- use_rethrow_when_possible
- use_to_and_as_if_applicable
48 changes: 26 additions & 22 deletions example/full_arith.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// Copyright (c) 2012, Google Inc. All rights reserved. Use of this source code
// is governed by a BSD-style license that can be found in the LICENSE file.

// Author: Paul Brauner ([email protected])
// Authors:
// Paul Brauner ([email protected])
// Dinesh Ahuja ([email protected])

library example;

Expand All @@ -10,35 +12,37 @@ import 'package:parsers/parsers.dart';
// Same example as example.dart, with the additional use of chainl1 which
// helps handling infix operators with the same precedence.

class Arith {
typedef MathFunction<T> = T Function(T a, T b);

digits2int(digits) => int.parse(digits.join());
class Arith {
int digits2int(List<String> digits) => int.parse(digits.join());

lexeme(parser) => parser < spaces;
token(str) => lexeme(string(str));
parens(parser) => parser.between(token('('), token(')'));
Parser<A> lexeme<A>(Parser<A> parser) => parser.thenDrop(spaces);
Parser<String> token(String str) => lexeme(string(str));
Parser<A> parens<A>(Parser<A> parser) =>
parser.between(token('('), token(')'));

get start => expr() < eof;
Parser<int> get start => expr().thenDrop(eof);

get comma => token(',');
get times => token('*');
get div => token('~/');
get plus => token('+');
get minus => token('-');
get number => lexeme(digit.many1) ^ digits2int;
Parser<String> get comma => token(',');
Parser<String> get times => token('*');
Parser<String> get div => token('~/');
Parser<String> get plus => token('+');
Parser<String> get minus => token('-');
Parser<int> get number => (lexeme(digit.many1).map(digits2int));

expr() => rec(term).chainl1(addop);
term() => rec(atom).chainl1(mulop);
atom() => number | parens(rec(expr));
Parser<int> expr() => rec(term).chainl1(addop);
Parser<int> term() => rec(atom).chainl1(mulop);
Parser<int> atom() => number.or(parens(rec(expr)));

get addop => (plus > success((x, y) => x + y))
| (minus > success((x, y) => x - y));
Parser<MathFunction> get addop => (plus.thenKeep(success((x, y) => x + y)))
.or(minus.thenKeep(success((x, y) => x - y)));

get mulop => (times > success((x, y) => x * y))
| (div > success((x, y) => x ~/ y));
Parser<MathFunction> get mulop => (times.thenKeep(success((x, y) => x * y)))
.or(div.thenKeep(success((x, y) => x ~/ y)));
}

main() {
final s = "1 * 2 ~/ 2 + 3 * (4 + 5 - 1)";
print(new Arith().start.parse(s)); // prints 25
const s = '1 * 2 ~/ 2 + 3 * (4 + 5 - 1)';
print(Arith().start.parse(s)); // prints 25
}
116 changes: 55 additions & 61 deletions example/mini_ast.dart
Original file line number Diff line number Diff line change
Expand Up @@ -82,107 +82,101 @@ class FieldDeclaration {
}

NamespaceDeclaration namespaceDeclarationMapping(doc, _, name, body, __) =>
new NamespaceDeclaration(name, body, doc);
NamespaceDeclaration(name, body, doc);

InterfaceDeclaration interfaceDeclarationMapping(doc, _, name, body, __) =>
new InterfaceDeclaration(name, body, doc);
InterfaceDeclaration(name, body, doc);

MethodDeclaration methodDeclarationRegularMapping(
doc, returnType, name, parameters, _) =>
new MethodDeclaration(returnType, name, parameters, doc);
doc, returnType, name, parameters, _) =>
MethodDeclaration(returnType, name, parameters, doc);

MethodDeclaration methodDeclarationReservedMapping(
doc, returnType, name, parameters, _) =>
new MethodDeclaration(new TypeAppl(returnType, null), name, parameters, doc);
doc, returnType, name, parameters, _) =>
MethodDeclaration(TypeAppl(returnType, null), name, parameters, doc);

DictionaryDeclaration dictionaryDeclarationMapping(
doc, _, name, body, __) =>
new DictionaryDeclaration(name, body, doc);
DictionaryDeclaration dictionaryDeclarationMapping(doc, _, name, body, __) =>
DictionaryDeclaration(name, body, doc);

FieldDeclaration fieldDeclarationMapping(doc, type, name, _) =>
new FieldDeclaration(type, name, doc);
FieldDeclaration(type, name, doc);

class DataCoreParser extends LanguageParsers {

DataCoreParser() : super(reservedNames: reservedNames,
// tells LanguageParsers to not handle comments
commentStart: "",
commentEnd: "",
commentLine: "");
DataCoreParser()
: super(
reservedNames: reservedNames,
// tells LanguageParsers to not handle comments
commentStart: "",
commentEnd: "",
commentLine: "");

Parser get docString => lexeme(_docString).many;

Parser get _docString =>
everythingBetween(string('//'), string('\n'))
| everythingBetween(string('/*'), string('*/'))
| everythingBetween(string('/**'), string('*/'));
everythingBetween(string('//'), string('\n')) |
everythingBetween(string('/*'), string('*/')) |
everythingBetween(string('/**'), string('*/'));

Parser get namespaceDeclaration =>
docString
+ reserved["namespace"]
+ identifier
+ braces(namespaceBody)
+ semi
^ namespaceDeclarationMapping;
docString +
reserved["namespace"] +
identifier +
braces(namespaceBody) +
semi ^
namespaceDeclarationMapping;

Parser get namespaceBody => body.many;

Parser get body => interfaceDeclaration | dictionaryDeclaration;

Parser get interfaceDeclaration =>
docString
+ reserved["interface"]
+ identifier
+ braces(interfaceBody)
+ semi
^ interfaceDeclarationMapping;
docString +
reserved["interface"] +
identifier +
braces(interfaceBody) +
semi ^
interfaceDeclarationMapping;

Parser get interfaceBody => method.many;

Parser get method => regularMethod | voidMethod;

Parser typeAppl() =>
identifier
+ angles(rec(typeAppl).sepBy(comma)).orElse([])
^ (c, args) => new TypeAppl(c, args);
identifier + angles(rec(typeAppl).sepBy(comma)).orElse([]) ^
(c, args) => TypeAppl(c, args);

Parser get parameter =>
(typeAppl() % 'type')
+ (identifier % 'parameter')
^ (t, p) => new Parameter(t, p);
(typeAppl() % 'type') + (identifier % 'parameter') ^
(t, p) => Parameter(t, p);

Parser get regularMethod =>
docString
+ typeAppl()
+ identifier
+ parens(parameter.sepBy(comma))
+ semi
^ methodDeclarationRegularMapping;
docString +
typeAppl() +
identifier +
parens(parameter.sepBy(comma)) +
semi ^
methodDeclarationRegularMapping;

Parser get voidMethod =>
docString
+ reserved['void']
+ identifier
+ parens(parameter.sepBy(comma))
+ semi
^ methodDeclarationReservedMapping;
docString +
reserved['void'] +
identifier +
parens(parameter.sepBy(comma)) +
semi ^
methodDeclarationReservedMapping;

Parser get dictionaryDeclaration =>
docString
+ reserved["dictionary"]
+ identifier
+ braces(dictionaryBody)
+ semi
^ dictionaryDeclarationMapping;
docString +
reserved["dictionary"] +
identifier +
braces(dictionaryBody) +
semi ^
dictionaryDeclarationMapping;

Parser get dictionaryBody => field.many;

Parser get field =>
docString
+ typeAppl()
+ identifier
+ semi
^ fieldDeclarationMapping;
docString + typeAppl() + identifier + semi ^ fieldDeclarationMapping;
}

final test = """
Expand Down Expand Up @@ -219,7 +213,7 @@ namespace datacore {
""";

void main() {
DataCoreParser dataCoreParser = new DataCoreParser();
DataCoreParser dataCoreParser = DataCoreParser();
NamespaceDeclaration namespaceDeclaration =
dataCoreParser.namespaceDeclaration.between(spaces, eof).parse(test);
print(namespaceDeclaration);
Expand Down
32 changes: 16 additions & 16 deletions example/mini_lang.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,32 @@ class MiniLang extends LanguageParsers {
get start => stmts().between(spaces, eof);

stmts() => stmt().endBy(semi);
stmt() => declStmt()
| assignStmt()
| ifStmt();
stmt() => declStmt() | assignStmt() | ifStmt();
// In a real parser, we would build AST nodes, but here we turn sequences
// into lists via the list getter for simplicity.
declStmt() => (reserved['var'] + identifier + symbol('=') + expr()).list;
assignStmt() => (identifier + symbol('=') + expr()).list;
ifStmt() => (reserved['if']
+ parens(expr())
+ braces(rec(stmts))
+ reserved['else']
+ braces(rec(stmts))).list;
ifStmt() => (reserved['if'] +
parens(expr()) +
braces(rec(stmts)) +
reserved['else'] +
braces(rec(stmts)))
.list;

expr() => disj().sepBy1(symbol('||'));
disj() => comp().sepBy1(symbol('&&'));
comp() => arith().sepBy1(symbol('<') | symbol('>'));
arith() => term().sepBy1(symbol('+') | symbol('-'));
term() => atom().withPosition.sepBy1(symbol('*') | symbol('/'));

atom() => floatLiteral
| intLiteral
| stringLiteral
| reserved['true']
| reserved['false']
| identifier
| parens(rec(expr));
atom() =>
floatLiteral |
intLiteral |
stringLiteral |
reserved['true'] |
reserved['false'] |
identifier |
parens(rec(expr));
}

final test = """
Expand All @@ -59,5 +59,5 @@ final test = """
""";

main() {
print(new MiniLang().start.parse(test));
print(MiniLang().start.parse(test));
}
Loading