import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Arrays;
import edu.uci.eecs.specCompiler.specExtraction.Construct;
import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct;
public static void main(String[] argvs)
throws ParseException, TokenMgrError {
try {
- File f = new File("./grammer/spec.txt");
+ File f = new File("./grammer/spec1.txt");
FileInputStream fis = new FileInputStream(f);
SpecParser parser = new SpecParser(fis);
- /*
+
ArrayList<String> content = new ArrayList<String>();
ArrayList<Construct> constructs = new ArrayList<Construct>();
ArrayList<String> headers = new ArrayList<String>();
for (int i = 0; i < constructs.size(); i++) {
System.out.println(constructs.get(i));
}
- */
- parser.Test();
+
+ //parser.Test();
System.out.println("Parsing finished!");
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
+
+ private static ArrayList<String> breakLines(String all) {
+ String lines[] = all.split("[\\r\\n]+");
+ return new ArrayList<String>(Arrays.asList(lines));
+ }
+
+
public static ArrayList<VariableDeclaration> getTemplateArg(String line)
throws ParseException {
InputStream input = new ByteArrayInputStream(line.getBytes());
-<*> SKIP :
+<IN_POTENTIAL_SPEC, IN_SPEC> SKIP :
{
" "
|
"/*": IN_COMMENT
}
+<DEFAULT> TOKEN: {
+ <ANY: ~[]>
+}
+
<*> SKIP : {
// "//" comment for the specification
<"//" (~["\n", "\r"])* (["\n", "\r"])>
}
-<IN_SPEC, DEFAULT> TOKEN :
+<IN_SPEC> TOKEN :
{
/* Specification & C/C++ shared tokens */
// Reserved keywords
}
{
{ type = ""; }
- ("const"
+ (<CONST>
{ type = "const"; }
)?
(((str = <STRUCT>.image | str = <CLASS>.image | str = <UNSIGNED>.image) { type = type + " " + str; })?
type = name.fullName;
})
)
- ((str = "const".image {
+ ((str = <CONST>.image {
if (!type.equals(""))
type = type + " " + str;
else
}
{
(str = <IDENTIFIER>.image {res = str;})
- ("<" str = Type() { res = res + "<" + str; }
- ("," str = Type() { res = res + ", " + str; })* ">"
+ (<OPEN_BRACKET> str = Type() { res = res + "<" + str; }
+ (<COMMA> str = Type() { res = res + ", " + str; })* <CLOSE_BRACKET>
{ res = res + ">"; }
)?
{
params = new ArrayList<VariableDeclaration>();
}
<TEMPLATE>
- "<"
+ <OPEN_BRACKET>
(type = <IDENTIFIER>.image
name = <IDENTIFIER>.image
{
}
)
- ("," type = <IDENTIFIER>.image
+ (<COMMA> type = <IDENTIFIER>.image
name = <IDENTIFIER>.image
{
params.add(new VariableDeclaration(type, name));
}
)*
- ">"
+ <CLOSE_BRACKET>
{
//System.out.println(params);
return params;
{
typeParams = new ArrayList<VariableDeclaration >();
}
- "("
+ <OPEN_PAREN>
((varDecl = TypeParam() {typeParams.add(varDecl);})
((<COMMA> varDecl = TypeParam() {typeParams.add(varDecl);}))*)?
- ")"
+ <CLOSE_PAREN>
{
return typeParams;
}
void Parse(File f, ArrayList<String> content, ArrayList<Construct> constructs, ArrayList<String> headers) :
{
Construct inst;
- ArrayList<String> code;
+ StringBuilder sb;
+ boolean flushSB;
}
{
{
_file = f;
_content = content;
_constructs = constructs;
+ sb = new StringBuilder();
+ }
+ (
+ (inst = ParseSpec()
+ {
+ _constructs.add(inst);
+ }
+ ) |
+ //((code = C_CPP_CODE(headers)) { _content.addAll(code); })
+ (
+ flushSB = OriginalCode(sb)
+ {
+ if (flushSB) {
+ sb = new StringBuilder();
+ }
+ }
+ )
+ )*
+ // For the last piece of code
+ {
+ _content.add(sb.toString());
+ }
+ <EOF>
+}
+
+// If true, there's a new line and sb should be flushed
+boolean OriginalCode(StringBuilder sb) :
+{
+ String str;
+}
+{
+ str = <ANY>.image
+ {
+ if (!str.equals("\n")) {
+ sb.append(str);
+ return false;
+ } else {
+ _content.add(sb.toString());
+ return true;
+ }
}
- ((inst = ParseSpec() { _constructs.add(inst); }) |
- ((code = C_CPP_CODE(headers)) { _content.addAll(code); })
- )* <EOF>
}
Construct ParseSpec() :
<GLOBAL_DEFINE>
(<DECLARE_STRUCT> (declareStruct = C_CPP_CODE(null) {
declareStructs.add(declareStruct); }))*
- (<DECLARE_VAR> ((declareVar = TypeParam() ";" {
+ (<DECLARE_VAR> ((declareVar = TypeParam() <SEMI_COLON> {
declareVars.add(declareVar); } )*))?
(<INIT_VAR> (code = C_CPP_CODE(null) { initVar = code; } ))?
(<DEFINE_FUNC> (defineFunc = C_CPP_CODE(null) { defineFuncs.add(defineFunc); }))*
--- /dev/null
+/* util.jj Grammer definition for utility functions */
+
+options {
+ STATIC = false;
+ JAVA_UNICODE_ESCAPE = true;
+}
+
+PARSER_BEGIN(UtilParser)
+package edu.uci.eecs.specCompiler.grammerParser.utilParser;
+import edu.uci.eecs.specCompiler.specExtraction.FunctionHeader;
+import edu.uci.eecs.specCompiler.specExtraction.QualifiedName;
+import edu.uci.eecs.specCompiler.specExtraction.VariableDeclaration;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.util.ArrayList;
+
+ public class UtilParser {
+ public static void main(String[] argvs)
+ throws ParseException, TokenMgrError {
+ try {
+ File f = new File("./grammer/spec1.txt");
+ FileInputStream fis = new FileInputStream(f);
+ UtilParser parser = new UtilParser(fis);
+
+ //parser.Test();
+ System.out.println("Parsing finished!");
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static ArrayList<VariableDeclaration> getTemplateArg(String line)
+ throws ParseException {
+ InputStream input = new ByteArrayInputStream(line.getBytes());
+ UtilParser parser = new UtilParser(input);
+ return parser.TemplateParamList();
+ }
+
+ public static FunctionHeader parseFuncHeader(String line)
+ throws ParseException {
+ InputStream input = new ByteArrayInputStream(line.getBytes());
+ UtilParser parser = new UtilParser(input);
+ return parser.FuncDecl();
+ }
+
+
+ public static String stringArray2String(ArrayList<String> content) {
+ StringBuilder sb = new StringBuilder();
+ if (content.size() == 1)
+ return content.get(0);
+ for (int i = 0; i < content.size(); i++) {
+ sb.append(content.get(i) + "\n");
+ }
+ return sb.toString();
+ }
+ }
+PARSER_END(UtilParser)
+
+SKIP :
+{
+ " "
+|
+ "\n"
+|
+ "\r"
+|
+ "\r\n"
+|
+ "\t"
+}
+
+TOKEN :
+{
+/* Specification & C/C++ shared tokens */
+// Reserved keywords
+ <CONST: "const">
+|
+ <STRUCT: "struct">
+|
+ <CLASS: "class">
+|
+ <UNSIGNED: "unsigned">
+|
+ <TEMPLATE: "template">
+|
+ <INLINE: "inline">
+|
+ <STATIC: "static">
+|
+ <FOR: "for">
+|
+ <#DIGIT: ["0"-"9"]>
+|
+ <#LETTER: ["a"-"z", "A"-"Z"]>
+|
+ <IDENTIFIER: (<LETTER> | "_") (<LETTER> | <DIGIT> | "_")*>
+|
+ <POUND: "#">
+|
+ <OPEN_BRACKET: "[">
+|
+ <CLOSE_BRACKET: "]">
+|
+ <EQUALS: "=">
+|
+ <OPEN_PAREN: "(">
+|
+ <CLOSE_PAREN: ")">
+|
+ <OPEN_BRACE: "{">
+|
+ <CLOSE_BRACE: "}">
+|
+ <HB_SYMBOL: "->">
+|
+ <COMMA: ",">
+|
+/* C/C++ only token*/
+ <DOT: ".">
+|
+ <DOLLAR: "$">
+|
+ <STAR: "*">
+|
+ <NEGATE: "~">
+|
+ <EXCLAMATION: "!">
+|
+ <AND: "&">
+|
+ <OR: "|">
+|
+ <MOD: "%">
+|
+ <PLUS: "+">
+|
+ <PLUSPLUS: "++">
+|
+ <MINUS: "-">
+|
+ <MINUSMINUS: "--">
+|
+ <DIVIDE: "/">
+|
+ <BACKSLASH: "\\">
+|
+ <LESS_THAN: "<">
+|
+ <GREATER_THAN: ">">
+|
+ <GREATER_EQUALS: ">=">
+|
+ <LESS_EQUALS: "<=">
+|
+ <LOGICAL_EQUALS: "==">
+|
+ <NOT_EQUALS: "!=">
+|
+ <LOGICAL_AND: "&&">
+|
+ <LOGICAL_OR: "||">
+|
+ <XOR: "^">
+|
+ <QUESTION_MARK: "?">
+|
+ <COLON: ":">
+|
+ <DOUBLECOLON: "::">
+|
+ <DOUBLELESSTHAN: "<<">
+|
+ <DOUBLEGREATERTHAN: ">>">
+|
+ <TRIPLEGREATERTHAN: ">>>">
+|
+ <PLUS_EQUALS: "+=">
+|
+ <MINUS_EQUALS: "-=">
+|
+ <TIMES_EQUALS: "*=">
+|
+ <DIVIDE_EQUALS: "/=">
+|
+ <MOD_EQUALS: "%=">
+|
+ <XOR_EQUALS: "^=">
+|
+ <OR_EQUALS: "|=">
+|
+ <AND_EQUALS: "&=">
+|
+ <SEMI_COLON: ";">
+|
+ <STRING_LITERAL:
+ "\""
+ ((~["\"","\\","\n","\r"])
+ | ("\\"
+ ( ["n","t","b","r","f","\\","'","\""]
+ | ["0"-"7"] ( ["0"-"7"] )?
+ | ["0"-"3"] ["0"-"7"]
+ ["0"-"7"]
+ )
+ )
+ )*
+ "\"">
+|
+ <CHARACTER_LITERAL:
+ "'"
+ ((~["'","\\","\n","\r"])
+ | ("\\"
+ (["n","t","b","r","f","\\","'","\""]
+ | ["0"-"7"] ( ["0"-"7"] )?
+ | ["0"-"3"] ["0"-"7"]
+ ["0"-"7"]
+ )
+ )
+ )
+ "'">
+|
+ < INTEGER_LITERAL:
+ <DECIMAL_LITERAL> (["l","L"])?
+ | <HEX_LITERAL> (["l","L"])?
+ | <OCTAL_LITERAL> (["l","L"])?>
+|
+ < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
+|
+ < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
+|
+ < #OCTAL_LITERAL: "0" (["0"-"7"])* >
+|
+ < FLOATING_POINT_LITERAL:
+ <DECIMAL_FLOATING_POINT_LITERAL>
+ | <HEXADECIMAL_FLOATING_POINT_LITERAL> >
+|
+ < #DECIMAL_FLOATING_POINT_LITERAL:
+ (["0"-"9"])+ "." (["0"-"9"])* (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
+ | "." (["0"-"9"])+ (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
+ | (["0"-"9"])+ <DECIMAL_EXPONENT> (["f","F","d","D"])?
+ | (["0"-"9"])+ (<DECIMAL_EXPONENT>)? ["f","F","d","D"]>
+|
+ < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
+|
+ < #HEXADECIMAL_FLOATING_POINT_LITERAL:
+ "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
+ | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?>
+|
+ < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ >
+|
+ < #SPACE: (" " | "\t")+>
+|
+ < #TO_END_OF_LINE: (~["\n"])+>
+|
+ /* Macro token */
+ <INCLUDE: "#" (<SPACE>)? "include" <SPACE> (<STRING_LITERAL> | "<" (<LETTER> | <DOT>)+ ">")>
+|
+ <DEFINE: "#" (<SPACE>)? <TO_END_OF_LINE>>
+}
+
+String Type() :
+{
+ String type;
+ String str;
+ QualifiedName name;
+}
+{
+ { type = ""; }
+ (<CONST>
+ { type = "const"; }
+ )?
+ (((str = <STRUCT>.image | str = <CLASS>.image | str = <UNSIGNED>.image) { type = type + " " + str; })?
+ (
+ name = ParseQualifiedName() {
+ if (!type.equals(""))
+ type = type + " " + name.fullName;
+ else
+ type = name.fullName;
+ })
+ )
+ ((str = <CONST>.image {
+ if (!type.equals(""))
+ type = type + " " + str;
+ else
+ type = str;
+ }) |
+ (str = <STAR>.image {
+ if (!type.equals(""))
+ type = type + " " + str;
+ else
+ type = str;
+ }) |
+ (str = <AND>.image {
+ if (!type.equals(""))
+ type = type + " " + str;
+ else
+ type = str;
+ })
+ )*
+ {
+ return type;
+ }
+}
+
+void Test() :
+{
+ String str;
+ FunctionHeader func;
+}
+{
+ /*
+ str = Type()
+ {
+ System.out.println(str);
+ }
+ */
+ func = FuncDecl()
+ {
+ System.out.println(func);
+ }
+
+}
+
+String ParameterizedName() :
+{
+ String res = "";
+ String str;
+}
+{
+ (str = <IDENTIFIER>.image {res = str;})
+ (<OPEN_BRACKET> str = Type() { res = res + "<" + str; }
+ (<COMMA> str = Type() { res = res + ", " + str; })* <CLOSE_BRACKET>
+ { res = res + ">"; }
+ )?
+ {
+ return res;
+ }
+}
+
+FunctionHeader FuncDecl() :
+{
+ String ret;
+ QualifiedName funcName;
+ ArrayList<VariableDeclaration> args;
+}
+{
+ (<STATIC> | <INLINE>)*
+ ret = Type()
+ funcName = ParseQualifiedName()
+ args = FormalParamList()
+ {
+ FunctionHeader res = new FunctionHeader(ret, funcName, args);
+ //System.out.println(res);
+ return res;
+ }
+}
+
+QualifiedName ParseQualifiedName() :
+{
+ String qualifiedName, str;
+}
+{
+ { qualifiedName = ""; }
+ (str = ParameterizedName() { qualifiedName = qualifiedName + str; } )
+ ( <DOUBLECOLON> (str = ParameterizedName() { qualifiedName = qualifiedName +
+ "::" + str; } ))*
+ {
+ QualifiedName res = new QualifiedName(qualifiedName);
+ //System.out.println(res);
+ return res;
+ }
+}
+
+ArrayList<VariableDeclaration> TemplateParamList() :
+{
+ ArrayList<VariableDeclaration> params;
+ String type;
+ String name;
+}
+{
+ {
+ params = new ArrayList<VariableDeclaration>();
+ }
+ <TEMPLATE>
+ <OPEN_BRACKET>
+ (type = <IDENTIFIER>.image
+ name = <IDENTIFIER>.image
+ {
+ params.add(new VariableDeclaration(type, name));
+ }
+ )
+
+ (<COMMA> type = <IDENTIFIER>.image
+ name = <IDENTIFIER>.image
+ {
+ params.add(new VariableDeclaration(type, name));
+ }
+ )*
+ <CLOSE_BRACKET>
+ {
+ //System.out.println(params);
+ return params;
+ }
+}
+
+ArrayList<VariableDeclaration > FormalParamList() :
+{
+ ArrayList<VariableDeclaration > typeParams;
+ VariableDeclaration varDecl;
+}
+{
+ {
+ typeParams = new ArrayList<VariableDeclaration >();
+ }
+ <OPEN_PAREN>
+ ((varDecl = TypeParam() {typeParams.add(varDecl);})
+ ((<COMMA> varDecl = TypeParam() {typeParams.add(varDecl);}))*)?
+ <CLOSE_PAREN>
+ {
+ return typeParams;
+ }
+}
+
+VariableDeclaration TypeParam() :
+{
+ String type, param;
+}
+{
+ (type = Type()) (param = <IDENTIFIER>.image)
+ {
+ return new VariableDeclaration(type, param);
+ }
+}
--- /dev/null
+package edu.uci.eecs.specCompiler.specExtraction;
+
+import java.util.HashMap;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.LineNumberReader;
+
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+/**
+ * <p>
+ * This class will scan all the input files, extract all the "special comments"
+ * (specifications). It should include information: 1. Beginning and end line of
+ * the specs; 2. The next two lines of code if it is interface constrcut.
+ * </p>
+ *
+ * @author peizhaoo
+ *
+ */
+public class SpecInfoScanner {
+ public final HashMap<File, Construct> constructs;
+
+ public SpecInfoScanner() {
+ constructs = new HashMap<File, Construct>();
+ }
+
+ /**
+ * <p>
+ * Scan
+ * </p>
+ *
+ * @param file
+ */
+ private void scanFile(File file) {
+ try {
+ FileReader fr = new FileReader(file);
+ LineNumberReader lnr = new LineNumberReader(fr);
+ String line = null;
+ // Info to keep when parsing the Spec
+ // 0 for default, 1 for potential sepc, 2 for in spec
+ int state = 0;
+ Pattern pBegin = Pattern.compile("^[\\s|\\t]*/**"), pEnd = Pattern
+ .compile("*/$");
+ while ((line = lnr.readLine()) != null) {
+ Matcher m1 = pBegin.matcher(line);
+ if (m1.matches())
+ state = 1; // Go to 'potential spec' state
+ if (state == 1) {
+
+ }
+ }
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void scanFiles(File[] files) {
+ for (int i = 0; i < files.length; i++) {
+ scanFile(files[i]);
+ }
+ }
+}