주로 내 자신의 학습 목적 및 재미를 위해 세미 자연 스크립트 언어를 만들려고합니다. 캐치 (catch)는 네이티브 C#에 있어야하고, 내 부분에 대한 구문 분석이나 어휘 분석이 필요하지 않기 때문에, 내가하는 일은 일반 구문 설탕을 통해 수행 할 수 있어야합니다.구문 분석을하지 않고 깨끗하고 자연스러운 스크립팅 기능
문장을 읽는 것처럼 다소 읽기 쉽기 때문에 특히 프로그래밍에 특히 유창하지 않은 사람들에게 읽기 쉽고 배우기 쉽습니다.하지만 기본 코드의 모든 기능을 사용자.
예를 들어, 완벽한 세계에서 자연 언어 (이 경우 영어)과 같습니다 실제로 스크립터는 것 거의 확실 의도 일을하기 위해이 같은 문장을 허용
When an enemy is within 10 units of player, the enemy attacks the player
C#에서 파서와 어휘 분석기를 통해 실행되는 문자열이어야합니다. 내 목표는 내가 자연스러운 무언가를 가지고있는 것이 아니라 스크립터가 문자열을 사용하여 스크립트를 작성하는 것을 원하지 않는다는 것입니다. 스크립터가 C#에 액세스 할 수 있고 구문 강조 표시, 인텔리 센스, IDE 디버깅 등을 할 수 있기를 바랍니다. 그래서 쉽게 읽을 수있는 내용을 얻으려고 시도하지만 native C#입니다. 극복 할 수있는 방법이 없다는 두 가지 주요 장애물은 .
, 쉼표 ,
및 빈 방법 ()
의 괄호를 제거하는 것입니다. 예를 들어,이 같은 일이 가능하지만 매우 깨끗하게 읽지 않습니다 :
// C#
When(Enemy.Condition(Conditions.isWithinDistance(Enemy, Player, 10))), Event(Attack(Enemy, Player))
기간과 괄호가 많은 경우에 하나의 공백으로 대체 할 수 있기 때문에 실제로, 훨씬 더 가까이 얻을 수있는 스칼라 같은 언어를 사용. 사실 당신은 더 동축 할 수있을 것,
이// Scala
When(Enemy is WithinDistance(Player, 10)) => Then(Attack From(Enemy, Player))
이 위의 코드는 실제로 당신에게 설정을 처리하는 엔진을 가정하고 컴파일합니다 : 예를 들어, 위의 진술을하고 스칼라에서 다음과 같이 보일 만들 수 괄호와 쉼표를 사용합니다. 위의 예에서 구문 설탕 없이는 스칼라에서,이 같은 더 많은 것 :
// Scala (without syntactical sugar)
When(Enemy.is(WithinDistance(Player, 10)) => Then(Attack().From(Enemy, Player))
결론은 내가 네이티브 C# .NET을 사용하여 첫 번째 스칼라 예처럼 뭔가에 가능한 한 가까이 할 수 있습니다. 내가 할 수있는 일이 정말로 없을 수도 있지만 더 자연스럽게 읽을 수있는 트릭을 시도해보고, 마침표, 괄호 및 쉼표를 알아낼 수 있습니다 (제외하면 의미가있는 경우 제외). 자연 언어에서도).
저는 다른 언어로 C#을 사용 해본 경험이 없으므로 C++의 매크로처럼 사용할 수있는 구문 트릭에 대해 알지 못할 수 있습니다. 매크로가 실제로 좋은 해결책이 될 수는 없겠지만, 아마도 문제가 더 커질 것이고 디버깅의 악몽이 될 것입니다.하지만 적어도 C++에서는 가능할 것입니다. C#에서도 가능한 것을 원하고 있습니까?
다음은 LINQ 및 Lambda 식을 사용하여 적은 양의 줄과 적은 기호로 동일한 작업량을 얻을 수 있으며 읽기를 영어에 가깝게 코드화 할 수 있습니다. 예를 들어 ID가있는 객체 쌍 사이에서 발생하는 세 가지 충돌의 예가 있습니다. ID가 5 인 객체로 모든 충돌을 수집 한 다음 해당 충돌을 쌍의 "첫 번째"ID로 정렬 한 다음 결과를 출력하려고합니다. 한 쌍.
struct CollisionPair : IComparable, IComparer
{
public int first;
public int second;
// Since we're sorting we'll need to write our own Comparer
int IComparer.Compare(object one, object two)
{
CollisionPair pairOne = (CollisionPair)one;
CollisionPair pairTwo = (CollisionPair)two;
if (pairOne.first < pairTwo.first)
return -1;
else if (pairTwo.first < pairOne.first)
return 1;
else
return 0;
}
// ...and our own compable
int IComparable.CompareTo(object two)
{
CollisionPair pairTwo = (CollisionPair)two;
if (this.first < pairTwo.first)
return -1;
else if (pairTwo.first < this.first)
return 1;
else
return 0;
}
}
static void Main(string[] args)
{
List<CollisionPair> collisions = new List<CollisionPair>
{
new CollisionPair { first = 1, second = 5 },
new CollisionPair { first = 2, second = 3 },
new CollisionPair { first = 5, second = 4 }
};
// In a script this would be all the code you needed, everything above
// would be part of the game engine
List<CollisionPair> sortedCollisionsWithFive = new List<CollisionPair>();
foreach (CollisionPair c in collisions)
{
if (c.first == 5 || c.second == 5)
{
sortedCollisionsWithFive.Add(c);
}
}
sortedCollisionsWithFive.Sort();
foreach (CollisionPair c in sortedCollisionsWithFive)
{
Console.WriteLine("Collision between " + c.first +
" and " + c.second);
}
}
그리고 지금 같은 예를 LINQ 및 람다와 함께 : 다음은 LINQ 및/또는 Lambra 표현하지 않고 이런 짓을 했을까 방법이다.이 예에서는 공지 사항 우리는 CollisionPair
모두 IComparable
및 IComparer
을 함께 모두 가지고 있지 않으며, Compare
및 CompareTo
방법으로 구현할 필요가 없습니다 :
struct CollisionPair
{
public int first;
public int second;
}
static void Main(string[] args)
{
List<CollisionPair> collisions = new List<CollisionPair>
{
new CollisionPair { first = 1, second = 5 },
new CollisionPair { first = 2, second = 3 },
new CollisionPair { first = 5, second = 4 }
};
// In a script this would be all the code you needed, everything above
// would be part of the game engine
(from c in collisions
where (c.first == 5 || c.second == 5)
orderby c.first select c).ForEach(c =>
Console.WriteLine("Collision between " + c.first +
" and " + c.second));
}
결국 우리가 LINQ로 남겨 그리고 람다 표현은 자연어에 가깝고 게임 엔진과 스크립트 모두에 대한 코드가 훨씬 적습니다. 이러한 종류의 변경은 실제로 내가 찾고있는 것이지만 LINQ와 Lambda는 둘 다 특정 구문으로 제한됩니다. 결국에는 일반과 같은 무언가가 아닙니다.
당신은 Coffeescript를 보았습니까? 구문에 대한 아이디어를 줄 수 있고 코드를 일반 JS로 구문 분석하는 방법을 볼 수 있습니다. 'food is not 'chocolate'' http://coffeescript.org/ – Jonathan
@Jonathan, 나는 네이티브 C#로 작성된 것을 필요로하며, 분석이나 어휘 분석이 필요하지 않습니다. 내 질문에 세부 사항을 추가하여 명확하게 설명하겠습니다. –
나는 다른 언어 임에도 불구하고 유사한 개념의 구현에 대한 정보를 제공하고 있었을 뿐이라는 질문을 이해했다. – Jonathan