Skip to content

Commit

Permalink
feat: prefix keywords with ^ to treat them as identifiers (#1172)
Browse files Browse the repository at this point in the history
### Summary of Changes

Keywords can now be prefixed with `^` to treat them as identifiers.
Previously, they had to be surrounded by backticks. The hat prefix is
more readable and shorter
  • Loading branch information
lars-reimann authored May 16, 2024
1 parent a216743 commit 90bd47c
Show file tree
Hide file tree
Showing 44 changed files with 88 additions and 90 deletions.
2 changes: 1 addition & 1 deletion docs/src/lexer/safe_ds_lexer/_safe_ds_lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
)

identifier_fragment = r"[_a-zA-Z][_a-zA-Z0-9]*"
identifier_regex = rf"{identifier_fragment}|`{identifier_fragment}`"
identifier_regex = rf"{identifier_fragment}|^{identifier_fragment}"
qualified_name_regex = rf"({identifier_regex})(\.({identifier_regex}))*"


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export class SafeDsValueConverter extends DefaultValueConverter {
protected override runConverter(rule: GrammarAST.AbstractRule, input: string, cstNode: CstNode): ValueType {
switch (rule.name.toUpperCase()) {
case 'ID':
return input.replaceAll('`', '');
return input.replace(/^\^/u, '');
case 'INT':
return ValueConverter.convertBigint(input);
case 'STRING':
Expand Down
2 changes: 1 addition & 1 deletion packages/safe-ds-lang/src/language/grammar/safe-ds.langium
Original file line number Diff line number Diff line change
Expand Up @@ -1097,7 +1097,7 @@ SdsColumn returns SdsColumn:
// Terminals
// -----------------------------------------------------------------------------

terminal ID returns string: IDENTIFIER | '`' IDENTIFIER '`';
terminal ID returns string: IDENTIFIER | '^' IDENTIFIER;
terminal fragment IDENTIFIER: /[_a-zA-Z][_a-zA-Z0-9]*/;

terminal FLOAT returns number
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const placeholdersMustNotBeAnAlias = (node: SdsPlaceholder, accept: Valid
export const placeholderShouldBeUsed =
(services: SafeDsServices) => (node: SdsPlaceholder, accept: ValidationAcceptor) => {
// Don't a warning if the placeholder's name starts with an underscore
if (node.name.startsWith('_')) {
if (!node.name || node.name.startsWith('_')) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class ExperimentalCell<T = Any?> {
*/
@Pure
@PythonName("not_")
fun `not`() -> result: ExperimentalCell<Boolean>
fun ^not() -> result: ExperimentalCell<Boolean>

/**
* Perform a boolean AND operation. This is equivalent to the `&` operator.
Expand All @@ -33,7 +33,7 @@ class ExperimentalCell<T = Any?> {
*/
@Pure
@PythonName("and_")
fun `and`(
fun ^and(
other: union<Boolean, ExperimentalCell<Boolean>>
) -> result: ExperimentalCell<Boolean>

Expand All @@ -49,7 +49,7 @@ class ExperimentalCell<T = Any?> {
*/
@Pure
@PythonName("or_")
fun `or`(
fun ^or(
other: union<Boolean, ExperimentalCell<Boolean>>
) -> result: ExperimentalCell<Boolean>

Expand Down Expand Up @@ -191,7 +191,7 @@ class ExperimentalCell<T = Any?> {
* }
*/
@Pure
fun `sub`(
fun ^sub(
other: Any
) -> result: ExperimentalCell

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class ExperimentalRow {
/**
* The schema of the row.
*/
attr `schema`: ExperimentalSchema
attr ^schema: ExperimentalSchema

/**
* Get the value of the specified column.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class ExperimentalTable(
/**
* The schema of the table.
*/
attr `schema`: ExperimentalSchema
attr ^schema: ExperimentalSchema

/**
* Create a table from a list of columns.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ class Row(
* @example
* pipeline example {
* val row = Row({"a": 1, "b": 2});
* val `schema` = row.`schema`;
* val ^schema = row.^schema;
* }
*/
attr `schema`: Schema
attr ^schema: Schema

/**
* Create a row from a dictionary that maps column names to column values.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ class Table(
* @example
* pipeline example {
* val table = Table({"a": [1, 2], "b": [3, 4]});
* val `schema` = table.`schema`;
* val ^schema = table.^schema;
* }
*/
attr `schema`: Schema
attr ^schema: Schema

/**
* Read data from a CSV file into a table.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@ const services = (await createSafeDsServices(EmptyFileSystem, { omitBuiltins: tr

describe('runConverter', () => {
describe('ID', () => {
it('should remove backticks (package)', async () => {
it('should remove hat (package)', async () => {
const code = `
package \`foo\`.bar
package ^foo.bar
`;

const module = await getNodeOfType(services, code, isSdsModule);
expect(module.name).toBe('foo.bar');
});

it('should remove backticks (declaration)', async () => {
it('should remove hat (declaration)', async () => {
const code = `
class \`MyClass\`
class ^MyClass
`;

const firstClass = await getNodeOfType(services, code, isSdsClass);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.callGraph.blockLambdaCall.argument.`segment`
package tests.callGraph.blockLambdaCall.argument.^segment

@Pure fun f()

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.callGraph.callable.`class`
package tests.callGraph.callable.^class

@Pure fun f() -> r: Any
@Pure fun g()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.callGraph.callable.`segment`
package tests.callGraph.callable.^segment

@Pure fun f() -> r: Any
@Pure fun g() -> r: Any
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.callGraph.expressionLambdaCall.argument.`segment`
package tests.callGraph.expressionLambdaCall.argument.^segment

@Pure fun f()

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.callGraph.segmentCall.argument.`segment`
package tests.callGraph.segmentCall.argument.^segment

@Pure fun f()

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.generator.runnerIntegration.expressions.`this`
package tests.generator.runnerIntegration.expressions.^this

class MyClass() {
@Pure
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
// $TEST$ no_syntax_error

class `_`
class `and`
class `annotation`
class `as`
class `attr`
class `class`
class `const`
class `enum`
class `false`
class `from`
class `fun`
class `import`
class `in`
class `internal`
class `literal`
class `not`
class `null`
class `or`
class `out`
class `package`
class `pipeline`
class `private`
class `schema`
class `static`
class `segment`
class `sub`
class `this`
class `true`
class `union`
class `unknown`
class `val`
class `where`
class `yield`
class ^_
class ^and
class ^annotation
class ^as
class ^attr
class ^class
class ^const
class ^enum
class ^false
class ^from
class ^fun
class ^import
class ^in
class ^internal
class ^literal
class ^not
class ^null
class ^or
class ^out
class ^package
class ^pipeline
class ^private
class ^schema
class ^static
class ^segment
class ^sub
class ^this
class ^true
class ^union
class ^unknown
class ^val
class ^where
class ^yield
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// $TEST$ no_syntax_error

class `Bla`
class ^Bla
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.partialValidation.recursiveCases.infixOperations.`and`
package tests.partialValidation.recursiveCases.infixOperations.^and

pipeline test {
// $TEST$ serialization false
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.partialValidation.recursiveCases.infixOperations.`and`
package tests.partialValidation.recursiveCases.infixOperations.^and

@Pure
fun pureFunction() -> result: Boolean
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.partialValidation.recursiveCases.infixOperations.`or`
package tests.partialValidation.recursiveCases.infixOperations.^or

pipeline test {
// $TEST$ serialization false
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.partialValidation.recursiveCases.infixOperations.`or`
package tests.partialValidation.recursiveCases.infixOperations.^or

@Pure
fun pureFunction() -> result: Boolean
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.partialValidation.recursiveCases.prefixOperations.`not`
package tests.partialValidation.recursiveCases.prefixOperations.^not

pipeline test {
// $TEST$ serialization true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.typing.expressions.`this`
package tests.typing.expressions.^this

// $TEST$ serialization unknown
annotation MyAnnotation(p: Any? = »this«)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ segment mySegment(
one: Contravariant<literal<1>>,
oneOrNull: Contravariant<literal<1, null>>,

`union`: Contravariant<union<Boolean, String>>,
^union: Contravariant<union<Boolean, String>>,
unionOrNull: Contravariant<union<Boolean, String?>>,

callable: Contravariant<() -> ()>,

// Named tuple types and static types are also not handled, but we can't test them here
) {
// $TEST$ serialization List<Contravariant<Nothing>>
»[one, `union`]«;
»[one, ^union]«;

// $TEST$ serialization List<Contravariant<Nothing>>
»[oneOrNull, `union`]«;
»[oneOrNull, ^union]«;

// $TEST$ serialization List<Contravariant<Nothing>>
»[one, unionOrNull]«;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class MyClass {

// $TEST$ no error r"The template expressions? .* cannot be interpreted."
@»PythonMacro«("myMethod2($this)")
fun myMethod2(`this`: Int)
fun myMethod2(^this: Int)

// $TEST$ no error "The template expression '$this' cannot be interpreted."
@»PythonMacro«("myMethod3($this)")
Expand All @@ -28,7 +28,7 @@ fun myFunction1(param: Int)

// $TEST$ no error r"The template expressions? .* cannot be interpreted."
@»PythonMacro«("myFunction2($this)")
fun myFunction2(`this`: Int)
fun myFunction2(^this: Int)

// $TEST$ error "The template expression '$this' cannot be interpreted."
@»PythonMacro«("myFunction3($this)")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package tests.validation.names.casing
// $TEST$ no warning "Names of annotations should be UpperCamelCase."
annotation »AnnotationUppercase1«
// $TEST$ no warning "Names of annotations should be UpperCamelCase."
annotation »`AnnotationUppercase2`«
annotation »^AnnotationUppercase2«
// $TEST$ warning "Names of annotations should be UpperCamelCase."
annotation »annotationLowercase«
// $TEST$ warning "Names of annotations should be UpperCamelCase."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class MyClass {
// $TEST$ no warning "Names of attributes should be lowerCamelCase."
attr »attributeLowercase1«: Int
// $TEST$ no warning "Names of attributes should be lowerCamelCase."
attr »`attributeLowercase2`«: Int
attr »^attributeLowercase2«: Int
// $TEST$ warning "Names of attributes should be lowerCamelCase."
attr »_attributeUnderscore«: Int
// $TEST$ warning "Names of attributes should be lowerCamelCase."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pipeline myPipeline1 {
// $TEST$ no warning "Names of block lambda results should be lowerCamelCase."
yield »lambdaResultLowercase1« = 1;
// $TEST$ no warning "Names of block lambda results should be lowerCamelCase."
yield »`lambdaResultLowercase2`« = 1;
yield »^lambdaResultLowercase2« = 1;
// $TEST$ warning "Names of block lambda results should be lowerCamelCase."
yield »_lambdaResultUnderscore« = 1;
// $TEST$ warning "Names of block lambda results should be lowerCamelCase."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package tests.validation.names.casing
// $TEST$ no warning "Names of classes should be UpperCamelCase."
class »ClassUppercase1«
// $TEST$ no warning "Names of classes should be UpperCamelCase."
class »`ClassUppercase2`«
class »^ClassUppercase2«
// $TEST$ warning "Names of classes should be UpperCamelCase."
class »classLowercase«
// $TEST$ warning "Names of classes should be UpperCamelCase."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ enum MyEnum {
// $TEST$ no warning "Names of enum variants should be UpperCamelCase."
»EnumVariantUppercase1«
// $TEST$ no warning "Names of enum variants should be UpperCamelCase."
»`EnumVariantUppercase2`«
»^EnumVariantUppercase2«
// $TEST$ warning "Names of enum variants should be UpperCamelCase."
»enumVariantLowercase«
// $TEST$ warning "Names of enum variants should be UpperCamelCase."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package tests.validation.names.casing
// $TEST$ no warning "Names of enums should be UpperCamelCase."
enum »EnumUppercase1«
// $TEST$ no warning "Names of enums should be UpperCamelCase."
enum »`EnumUppercase2`«
enum »^EnumUppercase2«
// $TEST$ warning "Names of enums should be UpperCamelCase."
enum »enumLowercase«
// $TEST$ warning "Names of enums should be UpperCamelCase."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ fun »FunctionUppercase«()
// $TEST$ no warning "Names of functions should be lowerCamelCase."
fun »functionLowercase1«()
// $TEST$ no warning "Names of functions should be lowerCamelCase."
fun »`functionLowercase2`«()
fun »^functionLowercase2«()
// $TEST$ warning "Names of functions should be lowerCamelCase."
fun »_functionUnderscore«()
// $TEST$ warning "Names of functions should be lowerCamelCase."
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// $TEST$ no warning "All segments of the qualified name of a package should be lowerCamelCase."
package »tests.validation.declarations.`lowercase1`«
package »tests.validation.declarations.^lowercase1«
Loading

0 comments on commit 90bd47c

Please sign in to comment.