2017-11-26 编程语言试验之Antlr4+Java实现圈2
"中文編程"知乎專欄原文
此文涉及的源碼版本: program-in-chinese/quan2
聲明 代碼來源 How to Create Language Using Antlr4
本作主要作為學(xué)習(xí)Antlr, 以及實(shí)踐中文命名之用. 目標(biāo)不是一個(gè)實(shí)用的編程語言.
個(gè)人感覺這樣可以比較容易的用原型來嘗試和演示不同語法設(shè)計(jì), 如果有更簡(jiǎn)單的途徑請(qǐng)不吝賜教. 歡迎各種自行修改~碰到任何問題也歡迎一同探討.
下面是"圈2"語言的示例代碼:
開始使 甲 為 5使 乙 為 10加 3 到 乙加 乙 到 甲加 甲 到 乙打印 乙打印 3 結(jié)束附上需要自行編寫的三個(gè)文件:
Antlr4的語法定義文件:
按照README說明, Antlr可以據(jù)此自動(dòng)生成四個(gè)分析器相關(guān)類文件. T前綴是由于Antlr約定大寫開頭是Token定義. 標(biāo)識(shí)符支持中文.
grammar 圈2; 程序 : '開始' 聲明+ '結(jié)束';聲明 : 賦值 | 加 | 打印 ;賦值 : '使' T標(biāo)識(shí)符 '為' (T數(shù) | T標(biāo)識(shí)符) ; 打印 : '打印' (T數(shù) | T標(biāo)識(shí)符) ; 加 : '加' (T數(shù) | T標(biāo)識(shí)符) '到' T標(biāo)識(shí)符 ;T標(biāo)識(shí)符 : ('a' .. 'z' | 'A' .. 'Z' | '\u4E00'..'\u9FA5' | '\uF900'..'\uFA2D')+ ; T數(shù) : [0-9]+ ; T空白 : [ \n\t]+ -> skip;定制監(jiān)聽器:
通過對(duì)每種語句分析后進(jìn)行對(duì)應(yīng)處理, 實(shí)質(zhì)上起了解釋器的作用.
public class 定制監(jiān)聽器 extends 圈2BaseListener {private Map<String, Integer> 變量表;public 定制監(jiān)聽器() {變量表 = new HashMap<>();}@Overridepublic void exit賦值(賦值Context 上下文) {// 賦值語句分析結(jié)束時(shí)運(yùn)行此方法String 變量名 = 上下文.T標(biāo)識(shí)符(0).getText();// 如果語句中有兩個(gè)變量(標(biāo)識(shí)符), 那么取第二個(gè)變量的值, 否則取數(shù)的值int 值 = 上下文.T標(biāo)識(shí)符().size() > 1? 變量表.get(上下文.T標(biāo)識(shí)符(1).getText()): Integer.parseInt(上下文.T數(shù)().getText());// 更新變量值變量表.put(變量名, 值);}@Overridepublic void exit加(加Context 上下文) {// 加語句分析結(jié)束時(shí)運(yùn)行此方法String 變量名 = 上下文.T標(biāo)識(shí)符().size() > 1 ? 上下文.T標(biāo)識(shí)符(1).getText() : 上下文.T標(biāo)識(shí)符(0).getText();int 添加值 = 上下文.T標(biāo)識(shí)符().size() > 1 ? 變量表.get(上下文.T標(biāo)識(shí)符(0).getText()): Integer.parseInt(上下文.T數(shù)().getText());變量表.put(變量名, 變量表.get(變量名) + 添加值);}@Overridepublic void exit打印(打印Context 上下文) {// 打印語句分析結(jié)束時(shí)運(yùn)行此方法String 輸出 = 上下文.T標(biāo)識(shí)符() == null ? 上下文.T數(shù)().getText() : 變量表.get(上下文.T標(biāo)識(shí)符().getText()).toString();System.out.println(輸出);} }運(yùn)行器:
讀取文件輸入, 調(diào)用附著了定制監(jiān)聽器的分析器
public class 運(yùn)行器 {public static void main(String[] 參數(shù)) {try {ANTLRInputStream 輸入 = new ANTLRInputStream(new FileInputStream(參數(shù)[0]));圈2Lexer 詞法分析器 = new 圈2Lexer(輸入);圈2Parser 語法分析器 = new 圈2Parser(new CommonTokenStream(詞法分析器));語法分析器.addParseListener(new 定制監(jiān)聽器());// 開始分析語法分析器.程序();} catch (IOException e) {e.printStackTrace();}} }尚未探索如何用Antlr4實(shí)現(xiàn)無空格語法設(shè)計(jì)(不允許標(biāo)識(shí)符中出現(xiàn)關(guān)鍵字應(yīng)該可以做到, 但那樣限制太多)
轉(zhuǎn)載于:https://www.cnblogs.com/program-in-chinese/p/10474443.html
總結(jié)
以上是生活随笔為你收集整理的2017-11-26 编程语言试验之Antlr4+Java实现圈2的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: script标签属性sync和defer
- 下一篇: Java 线程的生命周期