JavaCC使用小結
JavaCC是一個很不錯的詞法、語法解析器的生成器,只需要編寫規則就可以生成Java語言的詞法、語法解析器(新版本的JavaCC還支持C/C++作為目標語言)。JavaCC相當與Yacc/Bison+Lex/Flex很類似。
JavaCC首頁:
在首頁上下載的JavaCC是最新版的,使用方法和Bison一樣,在命令提示符或者終端中執行、獲得生成的結果。
也可已用javacc eclipse插件:
http://sourceforge.net/projects/eclipse-javacc/files/
下載插件、解壓之后,把plugins和features目錄下的文件分別拷貝到eclipse的相應目錄中即可。
不論哪種方式,所需編寫的規則都是一樣的。
通過JavaCC自帶的example和文檔其實就可以上手了,下面就簡單小結一下:
詞法和語法規則都寫在一個.jj的文件中。這個文件應該這樣寫:
1、開頭:
options { JDK_VERSION = "1.5"; STATIC = false; }
這個放在.jj文件的開頭,JDK_VERSION是所生成代碼適用的Jdk版本,1.5、1.6、1.7都可以,STATIC指示是否生成靜態的解析器類,還有其他選項,參考文檔。
2、主類
PARSER_BEGIN(Sparql) package cn.edu.ruc.iir.sparql; import cn.edu.ruc.iir.query.*; import cn.edu.ruc.iir.query.model.*; import cn.edu.ruc.iir.query.util.*; import java.text.*; public class Sparql { public static void main(String args []) throws ParseException { Sparql parser = new Sparql(System.in); int res = 0; while (true) { System.out.print("MyRDF >"); try { res = parser.one_query(); if (res == 0) {} else if (res == 1) { break; } else { System.out.println("Please correct your query."); } } catch (Exception e) { System.out.println("NOK."); System.out.println(e.getMessage()); parser.ReInit(System.in); } catch (Error e) { System.out.println("Oops."); System.out.println(e.getMessage()); break; } } } } PARSER_END(Sparql)
在PARSER_BEGIN和PARSER_END之間定義語法解析器的主類,這是整個解析程序的入口,里面主要有一些引用的包和類以及一個main方法(其他的方法由JavaCC生成)。由于上面把STATIC設為false了,所這這里需要創建一個parser對象,調用一次parser.one_query()就進行一條語句的解析并獲得解析的結果。
3、定義詞法規則
SKIP : { " " | "\t" | "\r" | "\n" } TOKEN : /* OPERATORS */ { < SELECT : "select" | "SELECT" > | < WHERE : "where" | "WHERE" > | < OBRACE : "{" > | < CBARCE : "}" > } TOKEN : { < UNKNOWN : "?" < KNOWN > > | < KNOWN : ([ "<", ">", "a"-"z", "A"-"Z", "0"-"9", ":", "/", "_", "-", "\"", "'", "~", "#" ])+ > | < MISSEDP : "[" "]" > | < EXIT : "exit" | "EXIT" > }
這部分定義詞法解析器的規則,SKIP定義要忽略的字符串,TOKEN定義要識別的字符串。注意,不是說先將輸入中符合SKIP規則的都去掉再進行解析,那樣的話是不科學的,正常的詞法解析都不會那么干,實際是順序處理輸入串的過程中,通過“大嘴法”識別盡可能長的子串。如果詞法規則有二義性,JavaCC會給出警告,一定不要忽略這些警告。
4、定義語法規則
JavaCC的語法單元形如這樣:
Token subject() : { Token token = null; } { token = < UNKNOWN > { return token; } | token = < KNOWN > { Token token1 = token; } ( "." token = < KNOWN > { token1.image += "."+ token.image; } )* { return token1; } }開頭是一個聲明,包括返回值類型、規則名和一個冒號。對于這樣一條語法規則,JavaCC就會在語法分析器類中生成一個同名的方法。緊接著的一對花括號中寫一些變量聲明。下一對花括號中寫該規則的具體內容。
一個語法單元中有多個規則時,用|分開。每個規則都有一系列詞法或語法單元組成,每個詞法或者語法單元之后跟著一對花括號,里面寫處理的代碼
基本上就是這樣了。
[引用請注明出處:http://blog.csdn.net/bhq2010/article/details/8763920]
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!