Skip to content

Commit

Permalink
Generator fragment for textmate grammars
Browse files Browse the repository at this point in the history
Signed-off-by: Sebastian Zarnekow <sebastian.zarnekow@gmail.com>
  • Loading branch information
szarnekow committed Apr 14, 2024
1 parent 9e3b1b4 commit f04982b
Show file tree
Hide file tree
Showing 11 changed files with 842 additions and 1 deletion.
4 changes: 3 additions & 1 deletion org.eclipse.xtext.xtext.generator/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ Require-Bundle: org.eclipse.xtext;bundle-version="2.35.0";x-installation:=greedy
org.eclipse.equinox.common;bundle-version="3.16.0",
org.antlr.runtime;bundle-version="[3.2.0,3.2.1)",
de.itemis.xtext.antlr;bundle-version="2.0.0";resolution:=optional;visibility:=reexport,
org.eclipse.jdt.core;bundle-version="3.29.0";resolution:=optional
org.eclipse.jdt.core;bundle-version="3.29.0";resolution:=optional,
com.google.gson;bundle-version="2.10.1";resolution:=optional
Import-Package: org.apache.log4j;version="1.2.24"
Export-Package: org.eclipse.xtext.xtext.generator;version="2.35.0",
org.eclipse.xtext.xtext.generator.builder;version="2.35.0",
Expand Down Expand Up @@ -46,6 +47,7 @@ Export-Package: org.eclipse.xtext.xtext.generator;version="2.35.0",
org.eclipse.xtext.xtext.generator.resourceFactory;version="2.35.0",
org.eclipse.xtext.xtext.generator.scoping;version="2.35.0",
org.eclipse.xtext.xtext.generator.serializer;version="2.35.0",
org.eclipse.xtext.xtext.generator.textmate;version="2.35.0";x-internal:=true,
org.eclipse.xtext.xtext.generator.types;version="2.35.0",
org.eclipse.xtext.xtext.generator.ui.codemining;version="2.35.0",
org.eclipse.xtext.xtext.generator.ui.compare;version="2.35.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/**
* Copyright (c) 2024 Sigasi (http://www.sigasi.com) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.xtext.xtext.generator.textmate;

import java.util.Optional;

import org.eclipse.emf.mwe2.runtime.Mandatory;
import org.eclipse.xtext.AbstractElement;
import org.eclipse.xtext.Grammar;
import org.eclipse.xtext.GrammarUtil;
import org.eclipse.xtext.Group;
import org.eclipse.xtext.TerminalRule;
import org.eclipse.xtext.UntilToken;

/**
* A TextMate rule that will parse the associated terminal rule and infer the TextMate equivalent automatically, if possible.
*
* @author David Medina
* @author Sebastian Zarnekow
* @since 2.35
*/
public class AutoRule extends TextMateRule {

@Mandatory
@Override
public void setTerminalRule(String terminalRule) {
super.setTerminalRule(terminalRule);
}

public Optional<TextMateRule> init(Grammar grammar, boolean ignoreCase, TerminalRuleToTextMateRule generator) {
TerminalRule terminal = (TerminalRule) GrammarUtil.findRuleForName(grammar, getTerminalRule());
if (terminal != null) {
Optional<TextMateRule> result = toBeginEndRule(terminal, generator).or(()->toMatchRule(terminal, generator));
return result.map(r->{
r.setName(Optional.ofNullable(getName()).orElseGet(()->toTextMateName(terminal, GrammarUtil.getSimpleName(grammar).toLowerCase())));
return r;
}).filter(r->r.getName() != null);
}
return Optional.empty();
}

protected Optional<TextMateRule> toBeginEndRule(TerminalRule rule, TerminalRuleToTextMateRule generator) {
AbstractElement alternatives = rule.getAlternatives();
if (alternatives instanceof Group) {
Group group = (Group) alternatives;
if (group.getElements().size() == 2 && group.getElements().get(1) instanceof UntilToken) {
String begin = generator.getMatchRegEx(group.getElements().get(0));
String end = generator.getMatchRegEx(((UntilToken)group.getElements().get(1)).getTerminal());
BeginEndRule result = new BeginEndRule();
result.setBegin(begin);
result.setEnd(end);
return Optional.of(result);
}
}
return Optional.empty();
}

protected Optional<TextMateRule> toMatchRule(TerminalRule rule, TerminalRuleToTextMateRule generator) {
try {
String match = generator.getMatchRegEx(rule);
MatchRule result = new MatchRule();
result.setMatch(match);
return Optional.of(result);
} catch(Exception e) {
return Optional.empty();
}
}

protected String toTextMateName(TerminalRule terminal, String langName) {
switch(terminal.getName()) {
case "SL_COMMENT": return "comment.line." + langName;
case "ML_COMMENT": return "comment.block." + langName;
case "STRING": return "string.quoted." + langName;
case "ID": return "variable." + langName;
case "INT": return "constant.numeric." + langName;
case "ANY_OTHER": return "invalid." + langName;
}
return null;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/**
* Copyright (c) 2024 Sigasi (http://www.sigasi.com) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.xtext.xtext.generator.textmate;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.eclipse.emf.mwe2.runtime.Mandatory;

import com.google.gson.annotations.Expose;

/**
* See the <a href="https://macromates.com/manual/en/language_grammars#rule_keys">TextMate specification</a>.
*
* @author David Medina
* @author Sebastian Zarnekow
* @since 2.35
*/
public class BeginEndRule extends TextMateRule {

@Expose private List<TextMateRule> patterns;
@Expose private String begin;
@Expose private String end;
@Expose private String contentName;
@Expose private Map<Integer, Capture> captures;
@Expose private Map<Integer, Capture> beginCaptures;
@Expose private Map<Integer, Capture> endCaptures;

@Mandatory
@Override
public void setName(String name) {
super.setName(name);
}

public String getBegin() {
return begin;
}
@Mandatory
public void setBegin(String begin) {
this.begin = begin;
}
public String getEnd() {
return end;
}
@Mandatory
public void setEnd(String end) {
this.end = end;
}

public void addMatchPattern(MatchRule rule) {
if (patterns == null) {
patterns = new ArrayList<>();
}
this.patterns.add(rule);
}

public void addBeginEndPattern(BeginEndRule rule) {
if (patterns == null) {
patterns = new ArrayList<>();
}
this.patterns.add(rule);
}

public String getContentName() {
return contentName;
}

public void setContentName(String contentName) {
this.contentName = contentName;
}

public void addInclude(String include) {
if (patterns == null) {
patterns = new ArrayList<>();
}
this.patterns.add(new IncludeRule(include));
}

public void addBeginEndCapture(Capture c) {
if (beginCaptures == null) {
beginCaptures = new TreeMap<>();
}
beginCaptures.put(c.getGroup(), c);
}

public void addEndCapture(Capture c) {
if (endCaptures == null) {
endCaptures = new TreeMap<>();
}
endCaptures.put(c.getGroup(), c);
}

public void addCapture(Capture c) {
if (captures == null) {
captures = new TreeMap<>();
}
captures.put(c.getGroup(), c);
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Copyright (c) 2024 Sigasi (http://www.sigasi.com) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.xtext.xtext.generator.textmate;

import com.google.gson.annotations.Expose;

/**
* See the <a href="https://macromates.com/manual/en/language_grammars#rule_keys">TextMate specification</a>.
*
* @author David Medina
* @author Sebastian Zarnekow
* @since 2.35
*/
public class Capture {

private int group;
@Expose private String name;

public int getGroup() {
return group;
}
public void setGroup(int group) {
this.group = group;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Copyright (c) 2024 Sigasi (http://www.sigasi.com) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.xtext.xtext.generator.textmate;

import com.google.gson.annotations.Expose;

/**
* See the <a href="https://macromates.com/manual/en/language_grammars#rule_keys">TextMate specification</a>.
*
* @author David Medina
* @author Sebastian Zarnekow
* @since 2.35
*/
public class IncludeRule extends TextMateRule {

@Expose private String include;

public IncludeRule(String include) {
this.include = include;
}

public String getInclude() {
return include;
}

public void setInclude(String include) {
this.include = include;
}



}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* Copyright (c) 2024 Sigasi (http://www.sigasi.com) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.xtext.xtext.generator.textmate;

import java.util.Map;
import java.util.TreeMap;

import org.eclipse.emf.mwe2.runtime.Mandatory;

import com.google.gson.annotations.Expose;

/**
* See the <a href="https://macromates.com/manual/en/language_grammars#rule_keys">TextMate specification</a>.
*
* @author David Medina
* @author Sebastian Zarnekow
* @since 2.35
*/
public class MatchRule extends TextMateRule {

@Expose private String match;
@Expose private Map<Integer, Capture> captures;

@Mandatory
@Override
public void setName(String name) {
super.setName(name);
}

public String getMatch() {
return match;
}

@Mandatory
public void setMatch(String match) {
this.match = match;
}

public void addCapture(Capture c) {
if (captures == null) {
captures = new TreeMap<>();
}
captures.put(c.getGroup(), c);
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* Copyright (c) 2024 Sigasi (http://www.sigasi.com) and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.xtext.xtext.generator.textmate;

/**
* Explicitely skip a terminal rule from auto-processing.
*
* @author David Medina
* @author Sebastian Zarnekow
* @since 2.35
*/
public class SkippedRule extends TextMateRule {

}
Loading

0 comments on commit f04982b

Please sign in to comment.