Skip to content

Instantly share code, notes, and snippets.

@watermint
Last active December 15, 2015 21:49
Show Gist options
  • Save watermint/5328609 to your computer and use it in GitHub Desktop.
Save watermint/5328609 to your computer and use it in GitHub Desktop.
Source:のAnalyzerをScalaで実装してみる
import scala.util.parsing.combinator.RegexParsers
import scala.util.parsing.input.Positional
object SimpleAnalyzer {
trait SearchKeyword extends Positional
case class KeywordIgnore(content:String) extends SearchKeyword
case class KeywordDefPackage(packageName:List[String]) extends SearchKeyword
case class KeywordDefClass(className:List[String]) extends SearchKeyword
case class KeywordRefSymbol(packageName:List[String]) extends SearchKeyword
case class KeywordComment(content:String) extends SearchKeyword
class JavaKeywordParsers extends RegexParsers {
def compilationUnit : Parser[List[SearchKeyword]] = rep(packageDeclaration | importDeclaration | comment)
def packageDeclaration : Parser[SearchKeyword] = "package" ~> positioned(packageName) <~ ";"
def packageName : Parser[SearchKeyword] =
(rep1(identifier <~ ".") ~ identifier) ^^ { p => KeywordDefPackage(p._1 :+ p._2) } |
identifier ^^ { p => KeywordDefPackage(List(p)) }
def importDeclaration : Parser[SearchKeyword] = "import" ~> positioned(importClassName) <~ ";"
def importClassName : Parser[SearchKeyword] =
(rep1(identifier <~ ".") ~ identifier) ^^ { c => KeywordRefSymbol(c._1 :+ c._2)} |
(rep1(identifier <~ ".") <~ "*") ^^ KeywordRefSymbol |
identifier ^^ { c => KeywordRefSymbol(List(c))}
def comment : Parser[SearchKeyword] = positioned(blockComment)
// regex: http://stackoverflow.com/questions/462843/improving-fixing-a-regex-for-c-style-block-comments
def blockComment : Parser[SearchKeyword] = "/*" ~> """(?>(?:(?>[^*]+)|\*(?!/))*)""".r <~ "*/" ^^ KeywordComment
def identifier = """[_a-zA-Z$][_a-zA-Z$]*""".r
def parse(input : String) = parseAll(compilationUnit, input)
}
def main(args: Array[String]) : Unit = {
val source =
"""
|/*
| * test
| */
|
|package org.watermint.sourcecolon.indexer;
|import org.watermint.sourcecolon.analyzer.*;
|import org.watermint.sourcecolon.Main;
|
""".stripMargin
val parser = new JavaKeywordParsers
val keywords = parser.parse(source)
keywords.get.foreach((k : SearchKeyword) => println(k.pos.line, k))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment