[educoder实训]用JAVACC生成并扩充C语言的语法分析器[待完善]
  • 实验平台JavaCC,Java Compiler Compiler, https://javacc.org/
  • 实训目标理解JavaCC源程序的结构规范,能够理解和设计JavaCC源程序,生成语法分析程序。
  • 语法规则JavaCC提供的Example Grammars(https://javacc.github.io/javacc/tutorials/examples.html#examples) 中的C语言语法规范CParser.JJ、以及任务描述提供的SQL规范。
  • 任务描述
    • 第1关:熟悉JavaCC 学习JavaCC的语法结构,编写JavaCC程序,生成能够解析正整数加法、减法、乘法的语法分析器。
    • 第2关:构建C语言的语法分析器 阅读并使用JavaCC提供的Example Grammars(https://javacc.github.io/javacc/tutorials/examples.html#examples) 中的C语言语法规范CParser.JJ的代码,生成完整的C语言的语法分析器。]
    • 第3关:用JavaCC为C语言扩充SQL语句 在第2关产生C语言语法分析器的基础上,为C语言增加对简单SQL语句的支持。

第1关:熟悉JavaCC

任务描述

本关任务:使用JavaCC生成能够解析正整数加法、减法、乘法的解析器。

相关知识

为了完成本关任务,你需要掌握:JavaCC的语法结构。

JavaCC简介

JavaCC是Java Complier Complier的缩写,是Java的解析器生成器兼扫描器生成器。为JavaCC描述好语法的规则,JavaCC就能够生成可以解析该语法的扫描器和解析器(的代码)了。

JavaCC语法结构

如果你之前已经学习了Flex和Bison,并亲手实践过了,那你将会发现,JavaCC的语法结构和它们十分类似。JavaCC的源文件是*.jj文件,其内容为:

options {
    JavaCC的选项
}
PARSER_BEGIN(解析器类名)
package 包名;
import 库名;
public class 解析器类名 {
    任意的Java代码
}
PARSER_END(解析器类名)
扫描器的描述
解析器的描述
一个例子

下面通过一个简单的例子介绍一下。 如下代码是一个解析正整数加法运算并进行计算的解析器的语法描述文件。

options {
    STATIC = false;
}
PARSER_BEGIN(Adder)
import java.io.*;
class Adder {
    public static void main(String[] args) {
        /*从命令行参数中读取待解析的字符串*/
        for (String arg : args) {
            try {
                System.out.println(evaluate(arg));
            } catch (ParseException ex) {
                System.err.println(ex.getMessage());
            }
        }
    }
    /*定义计算的方法*/
    public static long evaluate(String src) throws ParseException {
        Reader reader = new StringReader(src);
        return new Adder(reader).expr();
    }
}
PARSER_END(Adder)
/*忽视空格和换行*/
SKIP: { <[" ", "\t", "\r", "\n"]> }
TOKEN: {
    <INTEGER: (["0"-"9"])+>
}
/*定义规则*/
long expr():
{
    Token x, y;
}
{
    x=<INTEGER> "+" y=<INTEGER> <EOF>
    {
        return Long.parseLong(x.image) + Long.parseLong(y.image);
    }
}

上面的代码

编程要求

根据提示,在右侧编辑器补充代码,完成能够解析正整数加法(+)、减法(-)、乘法(*)的解析器。

测试说明

平台会对你编写的代码进行测试:

测试输入:4+5 12+7+9 27-9 2+7*9-2*6 预期输出:9 28 18 53

/* JavaCC 小测试 */
 /* 功能:实现一个能够进行加法(+),减法(-),乘方(^)的计算器 */
 /* 说明:在下面的begin和end之间添加代码,已经实现了简单的加法(+),你需要完成剩下的部分,加油吧! */
 /* 提示: */
 
options {
	STATIC = false;
}

PARSER_BEGIN(Calc)
import java.io.*;

class Calc {
	public static void main(String[] args) {
		for (String arg : args) {
			try { 
				System.out.println(evaluate(arg));
			} catch (ParseException ex) {
				System.err.println(ex.getMessage());
			}
		}
	}

	public static long evaluate(String src) throws ParseException {
		Reader reader = new StringReader(src);
		return new Calc(reader).start();
	}
}
PARSER_END(Calc)



SKIP:{" "}
SKIP:{"\n"|"\r"|"\r\n"}
TOKEN : /* OPERATORS */
{
  < PLUS : "+" >
| < MINUS : "-" >
| < MULTIPLY : "*" >

}
TOKEN:{< NUMBER : (["0"-"9"])+ >}

int start() throws NumberFormatException:
{
         Token t;
         int i;
         int value;
}

{
         value=term()
         (
            <PLUS>
            i= term()
            {value+=i;}
            | 
            < MINUS >
            i = term()
            { value -= i;} 
            
         )*
         <EOF>
         {return value;}
}

int term()throws NumberFormatException:
{
	int ivalue;
	int i;
}
{
	ivalue=primary()
	(
	  <MULTIPLY>
	   i=primary()
	   { ivalue*=i;}
	)*
	{return ivalue;}
}




int primary()throws NumberFormatException:
{
	Token t;
	int d;
}
{
	t=<NUMBER>
	{
		 return Integer.parseInt(t.image);
	}

}

第2关:构建C语言的语法分析器

任务描述

本关任务:用JavaCC生成C语言的语法分析器。

相关知识

经过上个任务的练习,相信大家对JavaCC已经有了初步的认识,接下来我们将通过实现C语言的语法分析器来加深理解。

语法规则

阅读并使用JavaCC提供的Grammar Repository(https://javacc.github.io/javacc/tutorials/examples.html#examples) 中的CParser.JJ的代码 注意:由于JavaCC官网的调整,原来在代码文件的提示中给出的https://javacc.org/grammar-library 已变更为 https://javacc.github.io/javacc/tutorials/examples.html#examples ,同时,文件名也由C.jj变更为CParser.jj。

编程要求

根据提示,实现C语言语法分析器框架。

注意,这个不需要你做功能上的扩充!


PARSER_BEGIN(CParser)

import java.util.*;

  public class CParser{

    // Hastable for storing typedef types
    private static Set types = new HashSet();

    // Stack for determining when the parser
    // is parsing a typdef definition.
    private static Stack typedefParsingStack = new Stack();

    // Returns true if the given string is
    // a typedef type.
    private static boolean isType(String type){
   	  return types.contains(type);
    }

    // Add a typedef type to those already defined
    private static void addType(String type){
   	  types.add(type);
    }

    // Prints out all the types used in parsing the c source
    private static void printTypes(){
      for (Iterator i = types.iterator(); i.hasNext();) {
        System.out.println(i.next());
      }
    }

    // Run the parser
    public static void main ( String args [ ] ) {
      CParser parser ;

  	  // Hack to include type "special types"
	    types.add("__signed__");
	    types.add("__const");
	    types.add("__inline__");
	    types.add("__signed");

      if(args.length == 0){
        System.out.println("C Parser Version 0.1Alpha:  Reading from standard input . . .");
        parser = new CParser(System.in);
      }
      else if(args.length == 1){
        System.out.println("C Parser Version 0.1Alpha:  Reading from file " + args[0] + " . . ." );
      try {
        parser = new CParser(new java.io.FileInputStream(args[0]));
      }
      catch(java.io.FileNotFoundException e){
        System.out.println("C Parser Version 0.1:  File " + args[0] + " not found.");
        return ;
        }
      }
      else {
        System.out.println("C Parser Version 0.1Alpha:  Usage is one of:");
        System.out.println("         java CParser < inputfile");
        System.out.println("OR");
        System.out.println("         java CParser inputfile");
        return ;
      }
      try {
        parser.TranslationUnit();
        System.out.println("C Parser Version 0.1Alpha:  Java program parsed successfully.");
      }
      catch(ParseException e){
        System.out.println("C Parser Version 0.1Alpha:  Encountered errors during parse.");
        e.printStackTrace();
      }
    }
  }

PARSER_END(CParser)

SKIP : {
 " "
|  "\t"
|  "\n"
|  "\r"
|  <"//" (~["\n","\r"])* ("\n" | "\r" | "\r\n")>
|  <"/*" (~["*"])* "*" ("*" | ~["*","/"] (~["*"])* "*")* "/">
| "#" : PREPROCESSOR_OUTPUT
}

<PREPROCESSOR_OUTPUT> SKIP:
{
     "\n" : DEFAULT
}

<PREPROCESSOR_OUTPUT> MORE:
{
 "\\\n"
 |
 "\\\r\n"
 |
 < ~[] >
}


TOKEN : {
 <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: (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? (["f","F","d","D"])? | "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])? | (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])? | (["0"-"9"])+ (<EXPONENT>)? ["f","F","d","D"]>
|  <#EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+>
|  <CHARACTER_LITERAL: "\'" (~["\'","\\","\n","\r"] | "\\" (["n","t","b","r","f","\\","\'","\""] | ["0"-"7"] (["0"-"7"])? | ["0"-"3"] ["0"-"7"] ["0"-"7"])) "\'">
|  <STRING_LITERAL: "\"" ( ~["\"","\\","\n","\r"] | "\\" ( ["n","t","b","r","f","\\","\'","\""] | ["0"-"7"] (["0"-"7"])?  | ["0"-"3"] ["0"-"7"] ["0"-"7"] | ( ["\n","\r"] | "\r\n")))* "\"">
}

TOKEN : {
	<CONTINUE: "continue"> |
	<VOLATILE: "volatile"> |
	<REGISTER: "register"> |
	<UNSIGNED: "unsigned"> |
	<TYPEDEF: "typedef"> |
	<DFLT: "default"> |
	<DOUBLE: "double"> |
	<SIZEOF: "sizeof"> |
	<SWITCH: "switch"> |
	<RETURN: "return"> |
	<EXTERN: "extern"> |
	<STRUCT: "struct"> |
	<STATIC: "static"> |
	<SIGNED: "signed"> |
	<WHILE: "while"> |
	<BREAK: "break"> |
	<UNION: "union"> |
	<CONST: "const"> |
	<FLOAT: "float"> |
	<SHORT: "short"> |
	<ELSE: "else"> |
	<CASE: "case"> |
	<LONG: "long"> |
	<ENUM: "enum"> |
	<AUTO: "auto"> |
	<VOID: "void"> |
	<CHAR: "char"> |
	<GOTO: "goto"> |
	<FOR: "for"> |
	<INT: "int"> |
	<IF: "if"> |
	<DO: "do">
}

TOKEN : {
 <IDENTIFIER: <LETTER> (<LETTER> | <DIGIT>)*>
|  <#LETTER: ["$","A"-"Z","_","a"-"z"]>
|  <#DIGIT: ["0"-"9"]>
}

void TranslationUnit() : {}
{
	(ExternalDeclaration())+
	{printTypes();}
}

void ExternalDeclaration() : {}
{
	( LOOKAHEAD( FunctionDefinition() ) FunctionDefinition() | Declaration())
}

void FunctionDefinition() : {}
{
	[LOOKAHEAD(DeclarationSpecifiers()) DeclarationSpecifiers()] Declarator() [ DeclarationList() ]
	CompoundStatement()
}

void Declaration() : {}
{
	DeclarationSpecifiers() [ InitDeclaratorList() ] ";"
}

void DeclarationList() : {}
{
	( LOOKAHEAD(Declaration()) Declaration() )+
}

void DeclarationSpecifiers() : {}
{
	  StorageClassSpecifier() [ LOOKAHEAD(DeclarationSpecifiers())
	        DeclarationSpecifiers() ] |
	  TypeSpecifier()  [ LOOKAHEAD(DeclarationSpecifiers())
	        DeclarationSpecifiers() ] |
	  TypeQualifier() [ LOOKAHEAD(DeclarationSpecifiers())
	        DeclarationSpecifiers() ]
}

void StorageClassSpecifier() : {}
{
	( <AUTO> | <REGISTER> | <STATIC> | <EXTERN> | <TYPEDEF>
	{
		typedefParsingStack.push(Boolean.TRUE);
	} )
}

void TypeSpecifier() : {}
{
	( <VOID> | <CHAR> | <SHORT> | <INT> | <LONG> | <FLOAT> | <DOUBLE> | <SIGNED> |
	  <UNSIGNED> | StructOrUnionSpecifier() | EnumSpecifier() | LOOKAHEAD( { isType(getToken(1).image) } )TypedefName() )
}

void TypeQualifier() : {}
{
	( <CONST> | <VOLATILE> )
}

void StructOrUnionSpecifier() : {}
{
	{
			typedefParsingStack.push(Boolean.FALSE);
	}

	StructOrUnion() ( LOOKAHEAD(3) [ <IDENTIFIER> ] "{" StructDeclarationList() "}" | <IDENTIFIER> )

	{
		typedefParsingStack.pop();
	}
}

void StructOrUnion() : {}
{
	( <STRUCT> | <UNION> )
}

void StructDeclarationList() : {}
{
	(StructDeclaration())+
}

void InitDeclaratorList() : {}
{
	InitDeclarator() ("," InitDeclarator())*
	{
		// Finished with a typedefDeclaration??
		if(!(typedefParsingStack.empty()) && ((Boolean)typedefParsingStack.peek()).booleanValue()){
		   	typedefParsingStack.pop();
	  }
	}
}

void InitDeclarator() : {}
{
	Declarator() [ "=" Initializer() ]
}

void StructDeclaration() : {}
{
	SpecifierQualifierList() StructDeclaratorList() ";"
}

void SpecifierQualifierList() : {}
{
	  TypeSpecifier() [ LOOKAHEAD(SpecifierQualifierList())
	        SpecifierQualifierList() ]|
	  TypeQualifier() [ LOOKAHEAD(SpecifierQualifierList())
	        SpecifierQualifierList() ]
}

void StructDeclaratorList() : {}
{
	StructDeclarator() ( "," StructDeclarator() )*
}

void StructDeclarator() : {}
{
	( LOOKAHEAD(3) Declarator() | [ Declarator() ] ":" ConstantExpression() )
}

void EnumSpecifier() : {}
{
	<ENUM> ( LOOKAHEAD(3) [ <IDENTIFIER> ] "{" EnumeratorList() "}" | <IDENTIFIER> )
}

void EnumeratorList() : {}
{
	Enumerator() ("," Enumerator())*
}

void Enumerator() : {}
{
	<IDENTIFIER> [ "=" ConstantExpression() ]
}

void Declarator() : {}
{
	[ Pointer() ] DirectDeclarator()
}

void DirectDeclarator() : { Token t;}
{
	( t = <IDENTIFIER>

	{ if(!(typedefParsingStack.empty()) && ((Boolean)typedefParsingStack.peek()).booleanValue()){
				addType(t.image);
	  }
	}
	 | "(" Declarator() ")" )
  
  { typedefParsingStack.push( Boolean.FALSE ); }

	( "[" [ ConstantExpression() ] "]" |
	    LOOKAHEAD(3) "(" ParameterTypeList() ")" |
	    "(" [ IdentifierList() ] ")" )*
      { typedefParsingStack.pop(); }
}

void Pointer() : {}
{
	"*" [ TypeQualifierList() ] [ Pointer() ]
}

void TypeQualifierList() : {}
{
	(TypeQualifier())+
}

void ParameterTypeList() : {}
{
	ParameterList() ["," "..." ]
}

void ParameterList() : {}
{
	ParameterDeclaration() (LOOKAHEAD(2) "," ParameterDeclaration())*
}

void ParameterDeclaration() : {}
{
	DeclarationSpecifiers() ( LOOKAHEAD(Declarator()) Declarator() | [ AbstractDeclarator() ] )
}

void IdentifierList() : {}
{
	<IDENTIFIER> ("," <IDENTIFIER>)*
}

void Initializer() : {}
{
	( AssignmentExpression() |
	  "{" InitializerList() [","] "}" )
}

void InitializerList() : {}
{
	Initializer() (LOOKAHEAD(2) "," Initializer())*
}

void TypeName() : {}
{
	SpecifierQualifierList() [ AbstractDeclarator() ]

}

void AbstractDeclarator() : {}
{
	( LOOKAHEAD(3) Pointer() |
	  [Pointer()] DirectAbstractDeclarator() )
}

void DirectAbstractDeclarator() : {}
{
	( LOOKAHEAD(2) "(" AbstractDeclarator() ")" |
	               "[" [ConstantExpression()] "]" |
	               "(" [ParameterTypeList()] ")" )

	  ( "[" [ ConstantExpression() ] "]" | "(" [ ParameterTypeList() ] ")" )*
}

void TypedefName() : {}
{
	<IDENTIFIER>
}

void Statement() : {}
{
	( LOOKAHEAD(2) LabeledStatement() |
	  ExpressionStatement() |
	  CompoundStatement() |
	  SelectionStatement() |
	  IterationStatement() |
	  JumpStatement() )
}

void LabeledStatement() : {}
{
	( <IDENTIFIER> ":" Statement() |
	  <CASE> ConstantExpression() ":" Statement() |
	  <DFLT> ":" Statement() )
}

void ExpressionStatement() : {}
{
	[ Expression() ] ";"
}

void CompoundStatement() : {}
{
	"{" [ LOOKAHEAD(DeclarationList()) DeclarationList() ]
	    [ StatementList() ]
	"}"
}

void StatementList() : {}
{
	(Statement())+
}

void SelectionStatement() : {}
{
	( <IF> "(" Expression() ")" Statement() [ LOOKAHEAD(2) <ELSE> Statement() ] |
	  <SWITCH> "(" Expression() ")" Statement() )
}

void IterationStatement() : {}
{
	( <WHILE> "(" Expression() ")" Statement() |
	  <DO> Statement() <WHILE> "(" Expression() ")" ";" |
	  <FOR> "(" [ Expression() ] ";" [ Expression() ] ";" [ Expression() ] ")" Statement() )
}

void JumpStatement() : {}
{
	( <GOTO> <IDENTIFIER> ";" |
	  <CONTINUE> ";" |
	  <BREAK> ";" |
	  <RETURN> [ Expression() ] ";" )
}

void Expression() : {}
{
	AssignmentExpression() ( "," AssignmentExpression() )*
}

void AssignmentExpression() : {}
{
	  LOOKAHEAD(UnaryExpression() AssignmentOperator()) UnaryExpression() AssignmentOperator() AssignmentExpression() |
	  LOOKAHEAD(3) ConditionalExpression()
}

void AssignmentOperator() : {}
{
	( "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | "&=" | "^=" | "|=" )
}

void ConditionalExpression() : {}
{
	LogicalORExpression() [ "?" Expression() ":" ConditionalExpression() ]
}

void ConstantExpression() : {}
{
	ConditionalExpression()
}

void LogicalORExpression() : {}
{
	LogicalANDExpression() [ "||" LogicalORExpression() ]
}

void LogicalANDExpression() : {}
{
	InclusiveORExpression() [ "&&" LogicalANDExpression() ]
}

void InclusiveORExpression() : {}
{
	ExclusiveORExpression() [ "|" InclusiveORExpression() ]
}

void ExclusiveORExpression() : {}
{
	ANDExpression() [ "^" ExclusiveORExpression() ]
}

void ANDExpression() : {}
{
	EqualityExpression() [ "&" ANDExpression() ]
}

void EqualityExpression() : {}
{
	RelationalExpression() [ ( "==" | "!=" ) EqualityExpression() ]
}

void RelationalExpression() : {}
{
	ShiftExpression() [ ( "<" | ">" | "<=" | ">=" ) RelationalExpression() ]
}

void ShiftExpression() : {}
{
	AdditiveExpression() [ ( "<<" | ">>" ) ShiftExpression() ]
}

void AdditiveExpression() : {}
{
	MultiplicativeExpression() [ ( "+" | "-" ) AdditiveExpression() ]
}

void MultiplicativeExpression() : {}
{
	CastExpression() [ ( "*" | "/" | "%" ) MultiplicativeExpression() ]
}

void CastExpression() : {}
{
	( LOOKAHEAD("(" TypeName() ")" CastExpression() ) "(" TypeName() ")" CastExpression() |
	  UnaryExpression() )
}

void UnaryExpression() : {}
{
	( LOOKAHEAD(3) PostfixExpression() |
	  "++" UnaryExpression() |
	  "--" UnaryExpression() |
	  UnaryOperator() CastExpression() |
	  <SIZEOF> ( LOOKAHEAD(UnaryExpression() ) UnaryExpression() | "(" TypeName() ")" ) )
}

void UnaryOperator() : {}
{
	( "&" | "*" | "+" | "-" | "~" | "!" )
}

void PostfixExpression() : {}
{
	PrimaryExpression() ( "[" Expression() "]" |
	                      "(" [ LOOKAHEAD(ArgumentExpressionList() ) ArgumentExpressionList() ] ")" |
	  					  "." <IDENTIFIER> |
	  					  "->" <IDENTIFIER> |
	  					  "++" |
	  					  "--" )*
}

void PrimaryExpression() : {}
{
	( <IDENTIFIER> |
	  Constant() |
	  "(" Expression() ")" )
}

void ArgumentExpressionList() : {}
{
	AssignmentExpression() ( "," AssignmentExpression() )*
}

void Constant() : {}
{
 <INTEGER_LITERAL> | <FLOATING_POINT_LITERAL> | <CHARACTER_LITERAL> | <STRING_LITERAL>
}

第3关:用JavaCC为C语言扩充SQL语句[待补充]

任务描述

本关任务:在上一个用JavaCC编写的C语言语法分析器上扩充对SQL的支持。

相关知识

为了完成本关任务,你需要掌握:1.读懂C.jj的代码,2.理解需要支持的SQL语句。

C.jj的代码已经在文件中给出了,注意不要修改类的名称。

测试文件的内容结构如下所示,即在C语言的基础上增加了一条合法调用SQL的语句,在{}之间可以有一条或者多条合法的SQL语句,注意这里sql关键字

/*...正常的C代码...*/
sql{SQL语句};
/*...正常的C代码...*/
SQL扩充内容

SQL是一种关系数据库的查询语言,有其独特的语法规范,本次实验只要求大家能够完成最常用的几个句型。 SQL语言有其保留字(关键字),可以是大写,也可以是小写,(但是不要混着写),本次实验中涉及的有:

DELETE(delete)
FROM(from)
WHERE(where)
AND(and)
OR(or)
INSERT(insert)
INTO(into)
VALUES(values)
SELECT(select)
UPDATE(update)
SET(set)

注意,下面出现的identifier标识符value数字字符串,[]表示里面的内容出现0次1次只需要完成下面给出的句子类型,其他的视为非法句子

  • DeleteStatement
    1. 'DELETE' 'FROM' identifier 'WHERE' identifier = value [ 'AND'|'OR' identifier = value ... ] ;
  • InsertStatement
    1. 'INSERT' 'INTO' identifier 'VALUES' ( value, value, ... ) ;
  • QueryStatement
    1. 'SELECT' * 'FROM' identifier [ 'WHERE' identifier = value [ 'AND'|'OR' identifier = value ... ] ] ;
    2. 'SELECT' identifier [ , identifier ... ] 'FROM' identifier [ 'WHERE' identifier = value [ 'AND'|'OR' identifier = value ... ] ] ;
  • UpdateStatement
    1. 'UPDATE' identifier 'SET' identifier = value [ 'WHERE' identifier = value [ 'AND'|'OR' identifier = value ... ] ] ;

为测试需要,当识别 SQL 语句时需要打印相应的字符串,例如测试程序如下:

测试程序1

返回的结果应该是:

测试结果1

标准如下:

sql{}; --> "Get some sql statements."
XX --> "Get a XX."

其中XX可以是:

DeleteStatement
InsertStatement
QueryStatement
UpdateStatement

编程要求

根据提示,在右侧编辑器补充代码。 注意,这里提供的代码与你第二关中完成的代码略有不同,若需要恢复最初的代码,请参考下面提供的:

PARSER_BEGIN(CSQLParser)
import java.util.*;
  public class CSQLParser{
    // Hastable for storing typedef types
    private static Set types = new HashSet();
    // Stack for determining when the parser
    // is parsing a typdef definition.
    private static Stack typedefParsingStack = new Stack();
    // Returns true if the given string is
    // a typedef type.
    private static boolean isType(String type){
         return types.contains(type);
    }
    // Add a typedef type to those already defined
    private static void addType(String type){
         types.add(type);
    }
    // Prints out all the types used in parsing the c source
    private static void printTypes(){
      for (Iterator i = types.iterator(); i.hasNext();) {
        System.out.println(i.next());
      }
    }
    // Run the parser
    public static void main ( String args [ ] ) {
      CSQLParser parser ;
        // Hack to include type "special types"
        types.add("__signed__");
        types.add("__const");
        types.add("__inline__");
        types.add("__signed");
      if(args.length == 0){
        System.out.println("CSQL Parser Version 0.1Alpha:  Reading from standard input . . .");
        parser = new CSQLParser(System.in);
      }
      else if(args.length == 1){
        System.out.println("CSQL Parser Version 0.1Alpha:  Reading from file " + args[0] + " . . ." );
      try {
        parser = new CSQLParser(new java.io.FileInputStream(args[0]));
      }
      catch(java.io.FileNotFoundException e){
        System.out.println("CSQL Parser Version 0.1:  File " + args[0] + " not found.");
        return ;
        }
      }
      else {
        System.out.println("CSQL Parser Version 0.1Alpha:  Usage is one of:");
        System.out.println("         java CSQLParser < inputfile");
        System.out.println("OR");
        System.out.println("         java CSQLParser inputfile");
        return ;
      }
      try {
        parser.TranslationUnit();
        System.out.println("CSQL Parser Version 0.1Alpha:  Java program parsed successfully.");
      }
      catch(ParseException e){
        System.out.println("CSQL Parser Version 0.1Alpha:  Encountered errors during parse.");
        e.printStackT\frace();
      }
    }
  }
PARSER_END(CSQLParser)
SKIP : {
 " "
|  "\t"
|  "\n"
|  "\r"
|  <"//" (~["\n","\r"])* ("\n" | "\r" | "\r\n")>
|  <"/*" (~["*"])* "*" ("*" | ~["*","/"] (~["*"])* "*")* "/">
| "#" : PREPROCESSOR_OUTPUT
}
<PREPROCESSOR_OUTPUT> SKIP:
{
     "\n" : DEFAULT
}
<PREPROCESSOR_OUTPUT> MORE:
{
 "\\\n"
 |
 "\\\r\n"
 |
 < ~[] >
}
TOKEN : {
 <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: (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? (["f","F","d","D"])? | "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])? | (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])? | (["0"-"9"])+ (<EXPONENT>)? ["f","F","d","D"]>
|  <#EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+>
|  <CHARACTER_LITERAL: "\'" (~["\'","\\","\n","\r"] | "\\" (["n","t","b","r","f","\\","\'","\""] | ["0"-"7"] (["0"-"7"])? | ["0"-"3"] ["0"-"7"] ["0"-"7"])) "\'">
|  <STRING_LITERAL: "\"" ( ~["\"","\\","\n","\r"] | "\\" ( ["n","t","b","r","f","\\","\'","\""] | ["0"-"7"] (["0"-"7"])?  | ["0"-"3"] ["0"-"7"] ["0"-"7"] | ( ["\n","\r"] | "\r\n")))* "\"">
}
TOKEN : {
    <CONTINUE: "continue"> |
    <VOLATILE: "volatile"> |
    <REGISTER: "register"> |
    <UNSIGNED: "unsigned"> |
    <TYPEDEF: "typedef"> |
    <DFLT: "default"> |
    <DOUBLE: "double"> |
    <SIZEOF: "sizeof"> |
    <SWITCH: "switch"> |
    <RETURN: "return"> |
    <EXTERN: "extern"> |
    <STRUCT: "struct"> |
    <STATIC: "static"> |
    <SIGNED: "signed"> |
    <WHILE: "while"> |
    <BREAK: "break"> |
    <UNION: "union"> |
    <CONST: "const"> |
    <FLOAT: "float"> |
    <SHORT: "short"> |
    <ELSE: "else"> |
    <CASE: "case"> |
    <LONG: "long"> |
    <ENUM: "enum"> |
    <AUTO: "auto"> |
    <VOID: "void"> |
    <CHAR: "char"> |
    <GOTO: "goto"> |
    <FOR: "for"> |
    <INT: "int"> |
    <IF: "if"> |
    <DO: "do">
}
TOKEN : {
 <IDENTIFIER: <LETTER> (<LETTER> | <DIGIT>)*>
|  <#LETTER: ["$","A"-"Z","_","a"-"z"]>
|  <#DIGIT: ["0"-"9"]>
}
void TranslationUnit() : {}
{
    (ExternalDeclaration())+
}
void ExternalDeclaration() : {}
{
    ( LOOKAHEAD( FunctionDefinition() ) FunctionDefinition() | Declaration())
}
void FunctionDefinition() : {}
{
    [LOOKAHEAD(DeclarationSpecifiers()) DeclarationSpecifiers()] Declarator() [ DeclarationList() ]
    CompoundStatement()
}
void Declaration() : {}
{
    DeclarationSpecifiers() [ InitDeclaratorList() ] ";"
}
void DeclarationList() : {}
{
    ( LOOKAHEAD(Declaration()) Declaration() )+
}
void DeclarationSpecifiers() : {}
{
      StorageClassSpecifier() [ LOOKAHEAD(DeclarationSpecifiers())
            DeclarationSpecifiers() ] |
      TypeSpecifier()  [ LOOKAHEAD(DeclarationSpecifiers())
            DeclarationSpecifiers() ] |
      TypeQualifier() [ LOOKAHEAD(DeclarationSpecifiers())
            DeclarationSpecifiers() ]
}
void StorageClassSpecifier() : {}
{
    ( <AUTO> | <REGISTER> | <STATIC> | <EXTERN> | <TYPEDEF>
    {
        typedefParsingStack.push(Boolean.TRUE);
    } )
}
void TypeSpecifier() : {}
{
    ( <VOID> | <CHAR> | <SHORT> | <INT> | <LONG> | <FLOAT> | <DOUBLE> | <SIGNED> |
      <UNSIGNED> | StructOrUnionSpecifier() | EnumSpecifier() | LOOKAHEAD( { isType(getToken(1).image) } )TypedefName() )
}
void TypeQualifier() : {}
{
    ( <CONST> | <VOLATILE> )
}
void StructOrUnionSpecifier() : {}
{
    {
            typedefParsingStack.push(Boolean.FALSE);
    }
    StructOrUnion() ( LOOKAHEAD(3) [ <IDENTIFIER> ] "{" StructDeclarationList() "}" | <IDENTIFIER> )
    {
        typedefParsingStack.pop();
    }
}
void StructOrUnion() : {}
{
    ( <STRUCT> | <UNION> )
}
void StructDeclarationList() : {}
{
    (StructDeclaration())+
}
void InitDeclaratorList() : {}
{
    InitDeclarator() ("," InitDeclarator())*
    {
        // Finished with a typedefDeclaration??
        if(!(typedefParsingStack.empty()) && ((Boolean)typedefParsingStack.peek()).booleanValue()){
               typedefParsingStack.pop();
      }
    }
}
void InitDeclarator() : {}
{
    Declarator() [ "=" Initializer() ]
}
void StructDeclaration() : {}
{
    SpecifierQualifierList() StructDeclaratorList() ";"
}
void SpecifierQualifierList() : {}
{
      TypeSpecifier() [ LOOKAHEAD(SpecifierQualifierList())
            SpecifierQualifierList() ]|
      TypeQualifier() [ LOOKAHEAD(SpecifierQualifierList())
            SpecifierQualifierList() ]
}
void StructDeclaratorList() : {}
{
    StructDeclarator() ( "," StructDeclarator() )*
}
void StructDeclarator() : {}
{
    ( LOOKAHEAD(3) Declarator() | [ Declarator() ] ":" ConstantExpression() )
}
void EnumSpecifier() : {}
{
    <ENUM> ( LOOKAHEAD(3) [ <IDENTIFIER> ] "{" EnumeratorList() "}" | <IDENTIFIER> )
}
void EnumeratorList() : {}
{
    Enumerator() ("," Enumerator())*
}
void Enumerator() : {}
{
    <IDENTIFIER> [ "=" ConstantExpression() ]
}
void Declarator() : {}
{
    [ Pointer() ] DirectDeclarator()
}
void DirectDeclarator() : { Token t;}
{
    ( t = <IDENTIFIER>
    { if(!(typedefParsingStack.empty()) && ((Boolean)typedefParsingStack.peek()).booleanValue()){
                addType(t.image);
      }
    }
     | "(" Declarator() ")" )
  { typedefParsingStack.push( Boolean.FALSE ); }
    ( "[" [ ConstantExpression() ] "]" |
        LOOKAHEAD(3) "(" ParameterTypeList() ")" |
        "(" [ IdentifierList() ] ")" )*
      { typedefParsingStack.pop(); }
}
void Pointer() : {}
{
    "*" [ TypeQualifierList() ] [ Pointer() ]
}
void TypeQualifierList() : {}
{
    (TypeQualifier())+
}
void ParameterTypeList() : {}
{
    ParameterList() ["," "..." ]
}
void ParameterList() : {}
{
    ParameterDeclaration() (LOOKAHEAD(2) "," ParameterDeclaration())*
}
void ParameterDeclaration() : {}
{
    DeclarationSpecifiers() ( LOOKAHEAD(Declarator()) Declarator() | [ Abst\fractDeclarator() ] )
}
void IdentifierList() : {}
{
    <IDENTIFIER> ("," <IDENTIFIER>)*
}
void Initializer() : {}
{
    ( AssignmentExpression() |
      "{" InitializerList() [","] "}" )
}
void InitializerList() : {}
{
    Initializer() (LOOKAHEAD(2) "," Initializer())*
}
void TypeName() : {}
{
    SpecifierQualifierList() [ Abst\fractDeclarator() ]
}
void Abst\fractDeclarator() : {}
{
    ( LOOKAHEAD(3) Pointer() |
      [Pointer()] DirectAbst\fractDeclarator() )
}
void DirectAbst\fractDeclarator() : {}
{
    ( LOOKAHEAD(2) "(" Abst\fractDeclarator() ")" |
                   "[" [ConstantExpression()] "]" |
                   "(" [ParameterTypeList()] ")" )
      ( "[" [ ConstantExpression() ] "]" | "(" [ ParameterTypeList() ] ")" )*
}
void TypedefName() : {}
{
    <IDENTIFIER>
}
void Statement() : {}
{
    ( LOOKAHEAD(2) LabeledStatement() |
      ExpressionStatement() |
      CompoundStatement() |
      SelectionStatement() |
      IterationStatement() |
      JumpStatement() )
}
void LabeledStatement() : {}
{
    ( <IDENTIFIER> ":" Statement() |
      <CASE> ConstantExpression() ":" Statement() |
      <DFLT> ":" Statement() )
}
void ExpressionStatement() : {}
{
    [ Expression() ] ";"
}
void CompoundStatement() : {}
{
    "{" [ LOOKAHEAD(DeclarationList()) DeclarationList() ]
        [ StatementList() ]
    "}"
}
void StatementList() : {}
{
    (Statement())+
}
void SelectionStatement() : {}
{
    ( <IF> "(" Expression() ")" Statement() [ LOOKAHEAD(2) <ELSE> Statement() ] |
      <SWITCH> "(" Expression() ")" Statement() )
}
void IterationStatement() : {}
{
    ( <WHILE> "(" Expression() ")" Statement() |
      <DO> Statement() <WHILE> "(" Expression() ")" ";" |
      <FOR> "(" [ Expression() ] ";" [ Expression() ] ";" [ Expression() ] ")" Statement() )
}
void JumpStatement() : {}
{
    ( <GOTO> <IDENTIFIER> ";" |
      <CONTINUE> ";" |
      <BREAK> ";" |
      <RETURN> [ Expression() ] ";" )
}
void Expression() : {}
{
    AssignmentExpression() ( "," AssignmentExpression() )*
}
void AssignmentExpression() : {}
{
      LOOKAHEAD(UnaryExpression() AssignmentOperator()) UnaryExpression() AssignmentOperator() AssignmentExpression() |
      LOOKAHEAD(3) ConditionalExpression()
}
void AssignmentOperator() : {}
{
    ( "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | "&=" | "^=" | "|=" )
}
void ConditionalExpression() : {}
{
    LogicalORExpression() [ "?" Expression() ":" ConditionalExpression() ]
}
void ConstantExpression() : {}
{
    ConditionalExpression()
}
void LogicalORExpression() : {}
{
    LogicalANDExpression() [ "||" LogicalORExpression() ]
}
void LogicalANDExpression() : {}
{
    InclusiveORExpression() [ "&&" LogicalANDExpression() ]
}
void InclusiveORExpression() : {}
{
    ExclusiveORExpression() [ "|" InclusiveORExpression() ]
}
void ExclusiveORExpression() : {}
{
    ANDExpression() [ "^" ExclusiveORExpression() ]
}
void ANDExpression() : {}
{
    EqualityExpression() [ "&" ANDExpression() ]
}
void EqualityExpression() : {}
{
    RelationalExpression() [ ( "==" | "!=" ) EqualityExpression() ]
}
void RelationalExpression() : {}
{
    ShiftExpression() [ ( "<" | ">" | "<=" | ">=" ) RelationalExpression() ]
}
void ShiftExpression() : {}
{
    AdditiveExpression() [ ( "<<" | ">>" ) ShiftExpression() ]
}
void AdditiveExpression() : {}
{
    MultiplicativeExpression() [ ( "+" | "-" ) AdditiveExpression() ]
}
void MultiplicativeExpression() : {}
{
    CastExpression() [ ( "*" | "/" | "%" ) MultiplicativeExpression() ]
}
void CastExpression() : {}
{
    ( LOOKAHEAD("(" TypeName() ")" CastExpression() ) "(" TypeName() ")" CastExpression() |
      UnaryExpression() )
}
void UnaryExpression() : {}
{
    ( LOOKAHEAD(3) PostfixExpression() |
      "++" UnaryExpression() |
      "--" UnaryExpression() |
      UnaryOperator() CastExpression() |
      <SIZEOF> ( LOOKAHEAD(UnaryExpression() ) UnaryExpression() | "(" TypeName() ")" ) )
}
void UnaryOperator() : {}
{
    ( "&" | "*" | "+" | "-" | "~" | "!" )
}
void PostfixExpression() : {}
{
    PrimaryExpression() ( "[" Expression() "]" |
                          "(" [ LOOKAHEAD(ArgumentExpressionList() ) ArgumentExpressionList() ] ")" |
                            "." <IDENTIFIER> |
                            "->" <IDENTIFIER> |
                            "++" |
                            "--" )*
}
void PrimaryExpression() : {}
{
    ( <IDENTIFIER> |
      Constant() |
      "(" Expression() ")" )
}
void ArgumentExpressionList() : {}
{
    AssignmentExpression() ( "," AssignmentExpression() )*
}
void Constant() : {}
{
 <INTEGER_LITERAL> | <FLOATING_POINT_LITERAL> | <CHARACTER_LITERAL> | <STRING_LITERAL>
}

注意:由于JavaCC官网的调整,原来在代码文件的提示中给出的https://javacc.org/grammar-library 已变更为 https://javacc.github.io/javacc/tutorials/examples.html#examples ,同时,文件名也由C.jj变更为CParser.jj。

测试说明

平台会对你编写的代码进行测试! 测试用例存储在test_cases文件夹下,可以实时查看。

  1. Test0.c 一个简单的C程序,不包含任何SQL语句。
  2. Test1.c 测试DeleteStatement
  3. Test2.c 测试InsertStatement
  4. Test3.c 测试QueryStatement
  5. Test4.c 测试UpdateStatement

参考链接

© 版权声明
THE END
喜欢就支持以下吧
点赞2赞赏
分享
评论 抢沙发

请登录后发表评论