/* * The MIT License (MIT) * * Copyright (c) 2016 hsz Jakub Chrzanowski <jakub@hsz.mobi> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package mobi.hsz.idea.latex.lang; import com.intellij.lang.ASTNode; import com.intellij.lang.Language; import com.intellij.lang.ParserDefinition; import com.intellij.lang.PsiParser; import com.intellij.lexer.Lexer; import com.intellij.openapi.project.Project; import com.intellij.psi.FileViewProvider; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.TokenType; import com.intellij.psi.tree.IFileElementType; import com.intellij.psi.tree.TokenSet; import mobi.hsz.idea.latex.lexer.LatexLexerAdapter; import mobi.hsz.idea.latex.parser.LatexParser; import mobi.hsz.idea.latex.psi.LatexFile; import mobi.hsz.idea.latex.psi.LatexTypes; import org.jetbrains.annotations.NotNull; /** * Defines the implementation of a parser for a custom language. * * @author Jakub Chrzanowski <jakub@hsz.mobi> * @since 0.1 */ public class LatexParserDefinition implements ParserDefinition { /** Whitespaces. */ public static final TokenSet WHITE_SPACES = TokenSet.create(TokenType.WHITE_SPACE); /** Regular comment started with # */ public static final TokenSet COMMENTS = TokenSet.create(LatexTypes.COMMENT); /** Latex instruction started with \ */ public static final TokenSet INSTRUCTIONS = TokenSet.create(LatexTypes.IDENTIFIER, LatexTypes.IDENTIFIER_BEGIN, LatexTypes.IDENTIFIER_END); /** Latex instruction's argument */ public static final TokenSet ARGUMENTS = TokenSet.create(LatexTypes.ARG); /** All brackets: braces, brackets, parenthesis */ public static final TokenSet BRACKETS = TokenSet.create( LatexTypes.LBRACE, LatexTypes.RBRACE, LatexTypes.LBRACKET, LatexTypes.RBRACKET, LatexTypes.LPAREN, LatexTypes.RPAREN ); /** Element type of the node describing a file in the specified language. */ public static final IFileElementType FILE = new IFileElementType(Language.findInstance(LatexLanguage.class)); /** * Returns the lexer for lexing files in the specified project. This lexer does not need to support incremental relexing - it is always * called for the entire file. * * @param project the project to which the lexer is connected. * @return the lexer instance. */ @NotNull @Override public Lexer createLexer(Project project) { return new LatexLexerAdapter(project); } /** * Returns the parser for parsing files in the specified project. * * @param project the project to which the parser is connected. * @return the parser instance. */ @Override public PsiParser createParser(Project project) { return new LatexParser(); } /** * Returns the element type of the node describing a file in the specified language. * * @return the file node element type. */ @Override public IFileElementType getFileNodeType() { return FILE; } /** * Returns the set of token types which are treated as whitespace by the PSI builder. * Tokens of those types are automatically skipped by PsiBuilder. Whitespace elements * on the bounds of nodes built by PsiBuilder are automatically excluded from the text * range of the nodes. * <p><strong>It is strongly advised you return TokenSet that only contains {@link com.intellij.psi.TokenType#WHITE_SPACE}, * which is suitable for all the languages unless you really need to use special whitespace token</strong> * * @return the set of whitespace token types. */ @NotNull @Override public TokenSet getWhitespaceTokens() { return WHITE_SPACES; } /** * Returns the set of token types which are treated as comments by the PSI builder. * Tokens of those types are automatically skipped by PsiBuilder. Also, To Do patterns * are searched in the text of tokens of those types. * * @return the set of comment token types. */ @NotNull @Override public TokenSet getCommentTokens() { return COMMENTS; } /** * Returns the set of token types which are treated as argument by the PSI builder. * * @return the set of argument token types. */ @NotNull public TokenSet getArgumentTokens() { return ARGUMENTS; } /** * Returns the set of token types which are treated as instructions by the PSI builder. * * @return the set of instruction token types. */ @NotNull public TokenSet getInstructionTokens() { return INSTRUCTIONS; } /** * Returns the set of token types which are treated as brackets by the PSI builder: [](){} * * @return the set of instruction token types. */ @NotNull public TokenSet getBracketTokens() { return BRACKETS; } /** * Returns the set of element types which are treated as string literals. "Search in strings" * option in refactorings is applied to the contents of such tokens. * * @return the set of string literal element types. */ @NotNull @Override public TokenSet getStringLiteralElements() { return TokenSet.EMPTY; } /** * Creates a PSI element for the specified AST node. The AST tree is a simple, semantic-free * tree of AST nodes which is built during the PsiBuilder parsing pass. The PSI tree is built * over the AST tree and includes elements of different types for different language constructs. * * @param node the node for which the PSI element should be returned. * @return the PSI element matching the element type of the AST node. */ @NotNull @Override public PsiElement createElement(ASTNode node) { return LatexTypes.Factory.createElement(node); } /** * Creates a PSI element for the specified virtual file. * * @param viewProvider virtual file. * @return the PSI file element. */ @Override public PsiFile createFile(FileViewProvider viewProvider) { return new LatexFile(viewProvider); } /** * Checks if the specified two token types need to be separated by a space according to the language grammar. * For example, in Java two keywords are always separated by a space; a keyword and an opening parenthesis may * be separated or not separated. This is used for automatic whitespace insertion during AST modification operations. * * @param left the first token to check. * @param right the second token to check. * @return the spacing requirements. */ @Override public SpaceRequirements spaceExistanceTypeBetweenTokens(ASTNode left, ASTNode right) { return SpaceRequirements.MAY; } }