Comments (53)
Было:
line_expr_7 = new_expr | invoke_expr
invoke_expr = value_expr [ invoke_list ]
Стало:
line_expr_7 = new_expr | invoke_expr | value_expr
invoke_expr = value_expr invoke_list
Зачем:
Исправляем баг с invoke_expr
, в который попадало всё что ни попади.
P.S. Тут актуален вопрос с переносами строк. У нас может парситься такой код?
var a = 1
+ 1
Если да, то в данном случае нужно быть осторожным, чтобы
var a = test
hello
не воспринялось, будто мы вызываем test
и передаем ей параметр hello
.
from lens.
Было:
literal = "()" | "null" | "true" | "false" | string | int
Стало:
literal = "()" | "null" | "true" | "false" | string | double | int
double = [0-9]+\.[0-9]+
Зачем:
Добавляем поддержку для чисел с плавающей запятой.
from lens.
Было:
new_expr = "new" ( new_array_expr | new_tuple_expr | new_obj_expr )
Стало:
new_expr = "new" ( new_array_expr | new_tuple_expr | new_list_expr | new_dict_expr | new_obj_expr )
new_list_expr = "<" enumeration_expr ">"
new_dict_expr = "{" dict_entry_expr { ";" dict_entry_expr } "}"
dict_entry_expr = value_expr "=>" value_expr
Зачем:
Добавляем поддержку для описанных нод NewListNode
и NewDictionaryNode
from lens.
Код
var a = 1
+ 1
у нас парситься не может, т.к. по более раннему соглашению в качестве вайтспейса мы рассматриваем только пробелы.
from lens.
Внёс в парсер все правки.
from lens.
Было:
assign_expr = type [ "::" identifier ] { accessor_expr } "=" expr
Стало:
assign_expr = ( type "::" identifier | identifier ) { accessor_expr } "=" expr
Зачем:
Исправляем баг при обработке кода типа a = b
.
from lens.
Было:
assign_expr = ( type "::" identifier | identifier ) { accessor_expr } "=" expr
value_expr = type { accessor_expr } | literal | type_operator_expr | "(" expr ")"
Стало:
assign_expr = lvalue "=" expr
lvalue = ( type "::" identifier | identifier ) { accessor_expr }
value_expr = literal | type_operator_expr | "(" expr ")" | lvalue
Зачем:
Исправить type { accessor_expr }
, чтобы поддерживался доступ к статическим переменным.
from lens.
Было:
block = NL block_line { block_line } | line_expr
Стало:
block = NL block_line { block_line } | local_stmt
Зачем:
Иначе получается, что
while (a > 10)
a = a - 1
парсится, а если записать в одну строку - то нет, что нелогично и неправильно.
from lens.
Все изменения внёс.
from lens.
Было:
invoke_list = ( { NL "<|" value_expr } NL ) | { value_expr }
Стало:
invoke_list = NL { IDENT "<|" expr NL } | { value_expr }
Зачем:
Чтобы при вызове функции с передачей параметров через оператор <|
не нужно было брать выражения в скобки. Кроме того, был пропущен необходимый IDENT
.
from lens.
Всё сделано.
from lens.
Было:
lvalue = ( type "::" identifier | identifier ) { accessor_expr }
Стало:
lvalue = [ type "::" ] identifier { accessor_expr } | "(" expr ")" accessor_expr { accessor_expr }
Зачем:
Исправляет баг, описанный в #36.
from lens.
Сделано.
from lens.
Закрою пока задачку, чтоб не мешалась. Если будут ещё изменения грамматики - можно будет переоткрыть.
from lens.
Было:
line_expr = line_expr_1 [ "as" type ]
Стало:
line_expr = line_expr_1 [ ( "as" | "is" ) type ]
Зачем:
Добавить поддержку оператора is
, предложенного в #63.
from lens.
Было:
type_operator_expr = ( "typeof" | "default" ) "(" type ")"
Стало:
type_operator_expr = ( "typeof" | "default" ) type
Зачем:
А нафига там скобки? В отличие от if
и while
, они не требуются для разделения выражений, а только утяжеляют синтаксис.
from lens.
Было:
invoke_list = NL { IDENT "<|" expr NL } | { value_expr }
Стало:
invoke_list = NL { IDENT "<|" ( byref_arg | expr ) NL } | { byref_arg | value_expr }
byref_arg = "ref" lvalue
Зачем:
Нужно как-то особым образом помечать byref-параметры. И в качестве их значений должно быть валидное lvalue-выражение.
from lens.
А нафига там скобки?
Убрал: 7853628.
from lens.
Нужно как-то особым образом помечать byref-параметры. И в качестве их значений должно быть валидное lvalue-выражение.
В схему парсинга вкрутил поддержку, но как мы должны их отмечать для компилятора? Напиши-ка тест.
from lens.
У FunctionArgument есть флаг IsByRef, или как-то так. Доберусь домой - напишу тест.
from lens.
Добавить поддержку оператора is, предложенного в #63.
Сделано: 19b9278.
from lens.
Было:
value_expr = lvalue | atomar_expr
Стало:
value_expr = rvalue | atomar_expr
rvalue = lvalue [ "." identifier type_params ]
Зачем:
Для #68 - чтобы можно было указывать type arguments, но только слева от знака равно и только после идентификатора.
В GetMemberNode
для этой цели добавлено поле TypeSignatures
.
from lens.
Было:
line_expr = line_expr_1 [ ( "as" | "is" ) type ]
Стало:
line_expr = line_expr_0 { NL IDENT "|>" identifier invoke_list }
line_expr_0 = line_expr_1 [ ( "as" | "is" ) type ]
Зачем:
Добавить поддержку вызова Extension-методов без лишних скобочек (#9).
Парситься должно так же, как если бы были скобки:
Enumerable::Range 1 100
|> Where (i:int) -> i % 2 == 0
|> Select (i:int) -> i * 2
((Enumerable::Range 1 100).Where (i:int) -> i % 2 == 0).Select (i:int) -> i * 2
from lens.
Было:
typedef_stmt = INDENT "|" identifier [ "of" type ] NL
Стало:
typedef_stmt = INDENT identifier [ "of" type ] NL
Зачем:
Палочка там лишняя.
from lens.
Было:
funcdef = "fun" identifier func_params "->" block NL
Стало:
funcdef = "fun" identifier "of" type func_params "->" block NL
Зачем:
Пока сделаем явное указание типа обязательным для всех функций.
from lens.
Было:
func_params = { identifier ":" [ ( "ref" | "out" ) ] type }
Стало:
func_params = { identifier ":" [ "ref" ] type }
Зачем:
Out-аргументы у нас не нужны (см #67)
from lens.
Было:
byref_arg = "ref" lvalue
Стало:
byref_arg = "(" "ref" lvalue ")" | "ref" lvalue
Зачем:
Чтобы ref-аргумент можно было также брать в скобки.
from lens.
Для #68 - чтобы можно было указывать type arguments, но только слева от знака равно и только после идентификатора.
В GetMemberNode для этой цели добавлено поле TypeSignatures.
Что-то я этого поля там не вижу. Есть какое-то поле TypeHints
, но по описанию совсем не похоже. Надо разобраться.
from lens.
rvalue = lvalue [ "." identifier type_params ]
заменил на
rvalue = lvalue [ type_params ]
потому что эти вещи явно были лишние.
from lens.
Это было задумано специально. Lvalue может быть также индексатором, а код
A[1]
явно некорректный. Указания типов могут идти только после идентификатора.
from lens.
Enumerable::Range 1 100
|> Where (i:int) -> i % 2 == 0
|> Select (i:int) -> i * 2
Парсер считает это более похожим на
(Enumerable::Range 1 (100
|> Where ...))
from lens.
Нет, это бессмысленно. У |>
должен быть другой приоритет, нежели у .
. Наверное, я натупил в грамматике. Поправишь?
from lens.
Тут всё вообще ужасно. Короче, лямбду нельзя писать в качестве однострочного параметра функции.
test
<| true
<| (a:double) ->
logger.log a
a ** 2
<| false"
работает (т.к. параметр с новой строки), а, например,
s.Where (i:int) -> i % 2 == 0
не работает. Это связано с тем, что
invoke_list = NL { IDENT "<|" ( byref_arg | expr ) NL } | { byref_arg | value_expr }
(в многострочном параметре expr
, а в однострочном - value_expr
). Попытка это исправить приводит нас вообще в ад какой-то - половина тестов разваливается.
from lens.
Предлагаю дропнуть эту ужасную фичу, пока не поздно.
from lens.
typedef_stmt
- готово.
from lens.
funcdef
Готово, но куда я должен записать тип функции? Такого поля в FunctionNode
нет.
from lens.
Что именно дропнуть? Однострочные лямбды или оператор <|
?
from lens.
Добавь тогда поле ReturnTypeSignature
.
from lens.
Out-аргументы у нас не нужны
Готово.
from lens.
Чтобы ref-аргумент можно было также брать в скобки.
Готово.
from lens.
Что именно дропнуть? Однострочные лямбды или оператор
<|
?
Наверное, однострочные лямбды. Из-за них проблема.
from lens.
Добавь тогда поле
ReturnTypeSignature
.
Готово.
from lens.
Это было задумано специально. Lvalue может быть также индексатором, а код
A[1]
явно некорректный. Указания типов могут идти только после идентификатора.
Здесь есть проблема - без моей правки lvalue
всегда "откусывал" слишком большую часть строки и, как следствие, код парсился неверно.
from lens.
Без однострочных лямбд грустно. Как тогда должен выглядеть linq-вызов из нескольких методов? Надо что-то придумать.
from lens.
Лямбду, вроде бы, можно передавать в качестве однострочного параметра, если взять ее в скобки. Там в скобках expr
, который может быть также block_expr
. Мне кажется, на данный момент это вполне достаточно. Если дойдем до Major 2, то там надо будет, конечно, перепродумать грамматику с учетом всех этих неудобностей.
from lens.
Enumerable::Range 1 100
|> Where (i:int) -> i % 2 == 0
|> Select (i:int) -> i * 2
Считаем, что это тоже поддерживается, но вот в такой форме:
(Enumerable::Range 1 100)
|> Where ((i:int) -> i % 2 == 0)
|> Select ((i:int) -> i * 2)
from lens.
value_expr = rvalue | atomar_expr
rvalue = lvalue [ "." identifier type_params ]
Я что-то не понимаю, или пример
Enumerable::Empty<int>
под эту грамматику не подходит? Нормально ли это?
Я бы предложил всё-таки оставить мой вариант. Да, он позволяет чуток больше, чем положено (параметризованные индексаторы). Но тут уже можно в компил-тайме кинуть эксепшен. Всё равно парсер не в состоянии проверить всё.
from lens.
Более того, так вообще ничего работать не будет - lvalue
захавал себе кусочек [ "." identifier
, так что всё поломалось.
from lens.
Эх, не хотел трогать грамматику, но придется один момент доделать.
Было:
block_expr = if_expr | while_expr | try_expr | lambda_expr
Стало:
block_expr = if_expr | while_expr | try_expr | throw_expr | lambda_expr
throw_expr = throw [ line_expr ]
Зачем:
Забыли throw!
from lens.
Нормально ли это?
Нет, пожалуй что не нормально. Давай сделаем так, как ты предложил, а я в compile-time буду проверять на GetArrayNode
.
from lens.
А почему выражение перед оператором |>
должно быть в скобках?
(Enumerable::Range 1 100)
|> Where ((i:int) -> i % 2 == 0)
|> Select ((i:int) -> i * 2)
У оператора |>
ведь самый низкий приоритет, по идее туда должно попадать любое выражение, не обязательно в скобках?
UPD
Не обязательно. Без скобок не только парсится, но и работает на ура!
from lens.
Было:
funcdef = "fun" identifier "of" type func_params "->" block NL
Стало:
funcdef = "fun" identifier [ "of" type ] func_params "->" block NL
Зачем:
Очень не хочется писать func test of unit
. Это последнее изменение в грамматике, обещаю! :)
from lens.
В этом тикете всё сделано. Если будут ещё изменения - лучше открывать отдельные тикеты, т.к. этот тикет слишком большой и неуправляемый - сложно понять, что сделано, а что нет, без разбиения на подзадачи.
from lens.
Related Issues (20)
- Операции над функциями
- Мульти-объявление неинициализированных переменных HOT 1
- Ошибка в грамматике
- Интерфейс контекстно-зависимой типизации
- Ошибка при сохранении сборки - файл занят
- Проблема с тестами Translations HOT 1
- Поддержка атрибута Obsolete
- Поддержка Expression<T>
- Fix continuous integration
- Grammar file gets included after package installing HOT 2
- RegisterFunction doesn't seem to work HOT 1
- Ошибка с замыканием в цикле
- Bad IL format HOT 1
- Verbatim strings
- Наведение порядка в коде HOT 1
- LE3063: Only public, static, non-generic methods can be imported! HOT 4
- Улучшение для вывода типов
- Портирование на .NET Core HOT 4
- Properly detect System.Private library
- RegexNamedGroupsTryParseNoThrow test doesn't work
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from lens.