日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

antlr idea 入门_ANTLR入门:构建简单的表达语言

發(fā)布時(shí)間:2023/12/3 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 antlr idea 入门_ANTLR入门:构建简单的表达语言 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

antlr idea 入門

這是該系列的第一篇文章。 本系列的目的是描述如何創(chuàng)建有用的語言和所有支持工具。

在本文中,我們將開始研究一種非常簡單的表達(dá)語言。 我們將在語言沙箱中構(gòu)建它,因此我們將其稱為語言Sandy 。

我認(rèn)為工具支持對(duì)于一種語言至關(guān)重要:因此,我們將從一種非常簡單的語言開始,但是我們將為此提供豐富的工具支持。 要從一種語言中受益,我們需要解析器,解釋器和編譯器,編輯器等。 在我看來,構(gòu)建簡單的解析器的材料很多,但是構(gòu)建使用語言的實(shí)用有效所需的其余基礎(chǔ)結(jié)構(gòu)的材料卻很少。

我想專注于這些方面,使語言小巧但完全有用。 然后,您將能夠有機(jī)地增長語言。

該代碼可在GitHub上找到: https : //github.com/ftomassetti/LangSandbox 。 本文中提供的代碼對(duì)應(yīng)于標(biāo)簽01_lexer。

語言

該語言將允許定義變量和表達(dá)式。 我們將支持:

  • 整數(shù)和十進(jìn)制文字
  • 變量定義和賦值
  • 基本數(shù)學(xué)運(yùn)算(加,減,乘,除)
  • 括號(hào)的用法

有效文件的示例:

var a = 10 / 3 var b = (5 + 3) * 2 var c = a / b

我們將使用的工具

我們將使用:

  • ANTLR生成詞法分析器和解析器
  • 使用Gradle作為我們的構(gòu)建系統(tǒng)
  • 用Kotlin編寫代碼。 鑒于我剛開始學(xué)習(xí)它,這將是非常基本的Kotlin。

設(shè)置項(xiàng)目

我們的構(gòu)建。 gradle文件將如下所示

buildscript {ext.kotlin_version = '1.0.3'repositories {mavenCentral()maven {name 'JFrog OSS snapshot repo'url 'https://oss.jfrog.org/oss-snapshot-local/'}jcenter()}dependencies {classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"} }apply plugin: 'kotlin' apply plugin: 'java' apply plugin: 'idea' apply plugin: 'antlr'repositories {mavenLocal()mavenCentral()jcenter() }dependencies {antlr "org.antlr:antlr4:4.5.1"compile "org.antlr:antlr4-runtime:4.5.1"compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version"testCompile 'junit:junit:4.12' }generateGrammarSource {maxHeapSize = "64m"arguments += ['-package', 'me.tomassetti.langsandbox']outputDirectory = new File("generated-src/antlr/main/me/tomassetti/langsandbox".toString()) } compileJava.dependsOn generateGrammarSource sourceSets {generated {java.srcDir 'generated-src/antlr/main/'} } compileJava.source sourceSets.generated.java, sourceSets.main.javaclean{delete "generated-src" }idea {module {sourceDirs += file("generated-src/antlr/main")} }

我們可以運(yùn)行:

  • ./gradlew想法來生成IDEA項(xiàng)目文件
  • ./gradlew generateGrammarSource生成ANTLR詞法分析器和解析器

實(shí)施詞法分析器

我們將在兩個(gè)單獨(dú)的文件中構(gòu)建詞法分析器和解析器。 這是詞法分析器:

lexer grammar SandyLexer;// Whitespace NEWLINE : '\r\n' | 'r' | '\n' ; WS : [\t ]+ ;// Keywords VAR : 'var' ;// Literals INTLIT : '0'|[1-9][0-9]* ; DECLIT : '0'|[1-9][0-9]* '.' [0-9]+ ;// Operators PLUS : '+' ; MINUS : '-' ; ASTERISK : '*' ; DIVISION : '/' ; ASSIGN : '=' ; LPAREN : '(' ; RPAREN : ')' ;// Identifiers ID : [_]*[a-z][A-Za-z0-9_]* ;

現(xiàn)在,我們可以簡單地運(yùn)行./ gradlew generateGrammarSource,并且將根據(jù)先前的定義為我們生成詞法分析器。

測(cè)試詞法分析器

測(cè)試始終很重要,但是在構(gòu)建語言時(shí)絕對(duì)至關(guān)重要:如果支持您的語言的工具不正確,這可能會(huì)影響您將為其構(gòu)建的所有程序。 因此,讓我們開始測(cè)試詞法分析器:我們只需要驗(yàn)證詞法分析器產(chǎn)生的標(biāo)記序列就是我們所關(guān)注的。

package me.tomassetti.sandyimport me.tomassetti.langsandbox.SandyLexer import org.antlr.v4.runtime.ANTLRInputStream import java.io.* import java.util.* import org.junit.Test as test import kotlin.test.*class SandyLexerTest {fun lexerForCode(code: String) = SandyLexer(ANTLRInputStream(StringReader(code)))fun lexerForResource(resourceName: String) = SandyLexer(ANTLRInputStream(this.javaClass.getResourceAsStream("/${resourceName}.sandy")))fun tokens(lexer: SandyLexer): List<String> {val tokens = LinkedList<String>()do {val t = lexer.nextToken()when (t.type) {-1 -> tokens.add("EOF")else -> if (t.type != SandyLexer.WS) tokens.add(lexer.ruleNames[t.type - 1])}} while (t.type != -1)return tokens}@test fun parseVarDeclarationAssignedAnIntegerLiteral() {assertEquals(listOf("VAR", "ID", "ASSIGN", "INTLIT", "EOF"),tokens(lexerForCode("var a = 1")))}@test fun parseVarDeclarationAssignedADecimalLiteral() {assertEquals(listOf("VAR", "ID", "ASSIGN", "DECLIT", "EOF"),tokens(lexerForCode("var a = 1.23")))}@test fun parseVarDeclarationAssignedASum() {assertEquals(listOf("VAR", "ID", "ASSIGN", "INTLIT", "PLUS", "INTLIT", "EOF"),tokens(lexerForCode("var a = 1 + 2")))}@test fun parseMathematicalExpression() {assertEquals(listOf("INTLIT", "PLUS", "ID", "ASTERISK", "INTLIT", "DIVISION", "INTLIT", "MINUS", "INTLIT", "EOF"),tokens(lexerForCode("1 + a * 3 / 4 - 5")))}@test fun parseMathematicalExpressionWithParenthesis() {assertEquals(listOf("INTLIT", "PLUS", "LPAREN", "ID", "ASTERISK", "INTLIT", "RPAREN", "MINUS", "DECLIT", "EOF"),tokens(lexerForCode("1 + (a * 3) - 5.12")))} }

結(jié)論和下一步

我們從第一步開始:設(shè)置項(xiàng)目并構(gòu)建詞法分析器。

使這種語言在實(shí)踐中可用之前,我們還有很長的路要走,但我們還是開始了。 接下來,我們將使用相同的方法來處理解析器:構(gòu)建一些簡單的東西,以便我們可以通過命令行進(jìn)行測(cè)試和編譯。

翻譯自: https://www.javacodegeeks.com/2016/07/getting-started-antlr-building-simple-expression-language.html

antlr idea 入門

總結(jié)

以上是生活随笔為你收集整理的antlr idea 入门_ANTLR入门:构建简单的表达语言的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。