Skip to content

C0语言的词法分析和抽象语法树(AST)分析器

License

Notifications You must be signed in to change notification settings

kibaamor/c0-parser

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

c0-parser

C0语言的词法分析和抽象语法树(AST)分析器

C0语言

C0是简化了C语言语法与编译过程得到的小型编程语言。在文档的最后有C0的完整文法定义。

保留了C中的:

  • 变量类型:int, char, double
  • 条件判断:if
  • 循环语句:for, while, do
  • 循环控制:break, continue
  • 输入输出:scan, print
  • 函数相关:return

目录主要结构

.
├── CMakeLists.txt ---------CMake配置文件
├── data -------------------用于测试的c0源文件
│   ├── func.c0 ------------测试函数
│   ├── helloworld.c0 ------最简单的程序
│   ├── loop.c0 ------------测试循环
│   └── var_decl.c0 --------测试变量声明
├── examples ---------------示例程序
│   ├── dump_token.cpp -----词法分析打印
│   └── rewrite_ast.cpp ----语法分析打印
├── LICENSE ----------------源码使用许可
├── README.md --------------本文件
├── scripts ----------------生成工程可以使用的脚本文件
├── src --------------------C0分析器和核心代码
└── test -------------------C0分析器测试代码

如何编译

需要的软件

  • Visual Studio 2015及以上(Windows)
  • Gcc 4.9.1 (Linux)
  • CMake 3.1及以上

编译步骤

打开命令行

# 下载源码
git clone https://github.com/KibaAmor/c0-parser.git

# 进入源码根目录
cd c0-parser

# 创建存放编译中间文件的目录
mkdir build

# 进入存放编译中间文件的目录
cd build

# 生成工程
cmake ..

# 编译工程
# Windows下直接用Visual Studio打开c0-parser.sln
c0-parser.sln
# Linux下使用下面的命令编译
make -j3

生成的可执行文件在存放编译中间文件的目录下面的bin文件夹中。

Windows下也可以运行源码根目录scripts目录下的gen_vs2015project.bat或者gen_vs2017project.bat来生成sln工程文件。

如何测试

Windows

在Visual Studio中编译工程中名为RUN_TESTS的项目,即可在Visual Studio的编译输出控制台中看到测试结果,也可以直接运行项目中test文件夹下的工程。

Linux

打开命令行

进入源码根目录
cd c-parser

# 进入存放编译中间文件的目录
cd build

# 运行所有测试
make test

附:完整的C0文法

<digit> ::= 
    '0'|<nonzero-digit>
<nonzero-digit> ::= 
    '1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'
<hexadecimal-digit> ::=
    <digit>|'a'|'b'|'c'|'d'|'e'|'f'|'A'|'B'|'C'|'D'|'E'|'F'

<integer-literal> ::= 
    <decimal-literal>|<hexadecimal-literal>
<decimal-literal> ::= 
    '0'|<nonzero-digit>{<digit>}
<hexadecimal-literal> ::= 
    ('0x'|'0X')<hexadecimal-digit>{<hexadecimal-digit>}


<nondigit> ::=    'a'|'b'|'c'|'d'|'e'|'f'|'g'|'h'|'i'|'j'|'k'|'l'|'m'|'n'|'o'|'p'|'q'|'r'|'s'|'t'|'u'|'v'|'w'|'x'|'y'|'z'|'A'|'B'|'C'|'D'|'E'|'F'|'G'|'H'|'I'|'J'|'K'|'L'|'M'|'N'|'O'|'P'|'Q'|'R'|'S'|'T'|'U'|'V'|'W'|'X'|'Y'|'Z'

<identifier> ::= 
    <nondigit>{<nondigit>|<digit>}
<reserved-word> ::= 
     'const'
    |'void'   |'int'    |'char'   |'double'
    |'struct'
    |'if'     |'else'   
    |'switch' |'case'   |'default'
    |'while'  |'for'    |'do'
    |'return' |'break'  |'continue' 
    |'print'  |'scan'


<char-literal> ::= 
    "'" (<c-char>|<escape-seq>) "'" 
<string-literal> ::= 
    '"' {<s-char>|<escape-seq>} '"'
<escape-seq> ::=  
      '\\' | "\'" | '\"' | '\n' | '\r' | '\t'
    | '\x'<hexadecimal-digit><hexadecimal-digit>

    
<sign> ::= 
    '+'|'-'
<digit-seq> ::=
    <digit>{<digit>}
<floating-literal> ::= 
     [<digit-seq>]'.'<digit-seq>[<exponent>]
    |<digit-seq>'.'[<exponent>]
    |<digit-seq><exponent>
<exponent> ::= 
    ('e'|'E')[<sign>]<digit-seq>
   
    
<unary-operator>          ::= '+' | '-'
<additive-operator>       ::= '+' | '-'
<multiplicative-operator> ::= '*' | '/'
<relational-operator>     ::= '<' | '<=' | '>' | '>=' | '!=' | '=='
<assignment-operator>     ::= '='   

    
<single-line-comment> ::=
    '//'{<any-char>}<LF>
<multi-line-comment> ::= 
    '/*'{<any-char>}'*/'  
    
    
<type-specifier>         ::= <simple-type-specifier>
<simple-type-specifier>  ::= 'void'|'int'|'char'|'double'
<const-qualifier>        ::= 'const'
    
    
<C0-program> ::= 
    {<variable-declaration>}{<function-definition>}


<variable-declaration> ::= 
    [<const-qualifier>]<type-specifier><init-declarator-list>';'
<init-declarator-list> ::= 
    <init-declarator>{','<init-declarator>}
<init-declarator> ::= 
    <identifier>[<initializer>]
<initializer> ::= 
    '='<expression>    

    
<function-definition> ::= 
    <type-specifier><identifier><parameter-clause><compound-statement>

<parameter-clause> ::= 
    '(' [<parameter-declaration-list>] ')'
<parameter-declaration-list> ::= 
    <parameter-declaration>{','<parameter-declaration>}
<parameter-declaration> ::= 
    [<const-qualifier>]<type-specifier><identifier>

    
<compound-statement> ::= 
    '{' {<variable-declaration>} <statement-seq> '}'
<statement-seq> ::= 
    {<statement>}
<statement> ::= 
     <compound-statement>
    |<condition-statement>
    |<loop-statement>
    |<jump-statement>
    |<print-statement>
    |<scan-statement>
    |<assignment-expression>';'
    |<function-call>';'
    |';'   
    
    
<condition> ::= 
     <expression>[<relational-operator><expression>] 
   
<condition-statement> ::= 
     'if' '(' <condition> ')' <statement> ['else' <statement>]
    |'switch' '(' <expression> ')' '{' {<labeled-statement>} '}'

<labeled-statement> ::= 
     'case' (<integer-literal>|<char-literal>) ':' <statement>
    |'default' ':' <statement>

    
<loop-statement> ::= 
    'while' '(' <condition> ')' <statement>
   |'do' <statement> 'while' '(' <condition> ')' ';'
   |'for' '('<for-init-statement> [<condition>]';' [<for-update-expression>]')' <statement>

<for-init-statement> ::= 
    [<assignment-expression>{','<assignment-expression>}]';'
<for-update-expression> ::=
    (<assignment-expression>|<function-call>){','(<assignment-expression>|<function-call>)}


<jump-statement> ::= 
     'break' ';'
    |'continue' ';'
    |<return-statement>
<return-statement> ::= 'return' [<expression>] ';'
    
    
<scan-statement> ::= 
    'scan' '(' <identifier> ')' ';'
<print-statement> ::= 
    'print' '(' [<printable-list>] ')' ';'
<printable-list>  ::= 
    <printable> {',' <printable>}
<printable> ::= 
    <expression> | <string-literal>

<assignment-expression> ::= 
    <identifier><assignment-operator><expression>
    
   
  
<expression> ::= 
    <additive-expression>
<additive-expression> ::= 
     <multiplicative-expression>{<additive-operator><multiplicative-expression>}
<multiplicative-expression> ::= 
     <cast-expression>{<multiplicative-operator><cast-expression>}
<cast-expression> ::=
    {'('<type-specifier>')'}<unary-expression>
<unary-expression> ::=
    [<unary-operator>]<primary-expression>
<primary-expression> ::=  
     '('<expression>')' 
    |<identifier>
    |<integer-literal>
    |<char-literal>
    |<floating-literal>
    |<function-call>

<function-call> ::= 
    <identifier> '(' [<expression-list>] ')'
<expression-list> ::= 
    <expression>{','<expression>}

About

C0语言的词法分析和抽象语法树(AST)分析器

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages