JFLEX:创建自定义函数来计算字符数

时间:2018-03-24 23:30:44

标签: character jflex custom-function

我有一个项目是使用JFLEX为一个组合语言编写词法分析器。它是一种语法简单的语言,包括简单的变量,如字符串和字符整数和浮点数。但是我的角色有问题。我创建了一个类似于STRING的状态,名为CHAR,它使用单引号。不幸的是初始化如'你好'是可以接受的那么有没有办法创建一个自定义函数来计算字符数,如果它的大小等于1则打印字符变量,否则抛出异常?我搜索了很多但找不到答案。到目前为止,这是我的代码:

import static java.lang.System.out;

%%

%class Lexer
%unicode
%public
%final
%integer
%line
%column

%{
    // user custom code 

    StringBuffer sb = new StringBuffer();

%}

LineTerminator = \r|\n|\r\n
WhiteSpace     = {LineTerminator} | [ \t\f] 
Comment        = "/*" [^*] ~"*/" | "/*" "*"+ "/"

Identifier     = [:jletter:] [:jletterdigit:]*
IntegerLiteral = 0 | [1-9][0-9]*

Exponent= [eE][\+\-]?[0-9]+
Float1= [0-9]+ \. [0-9]+ {Exponent}?
Float2= \. [0-9]+ {Exponent}?
Float3= [0-9]+ \. {Exponent}?
Float4= [0-9]+ {Exponent}
FloatLiteral   = {Float1} | {Float2} | {Float3} | {Float4}


%state STRING, CHAR

%%

/* reserved keywords */
    <YYINITIAL>"float"                         { out.println("FLOAT"); } 
    <YYINITIAL>"int"                          { out.println("INTEGER"); }
    <YYINITIAL>"char"                         { out.println("CHAR"); }
    <YYINITIAL>"break"                        { out.println("BREAK"); }
    <YYINITIAL>"print"                        { out.println("PRINT"); }
    <YYINITIAL>"while"                        { out.println("WHILE"); }
    <YYINITIAL>"if"                           { out.println("IF"); }
    <YYINITIAL>"else"                         { out.println("ELSE"); }
    <YYINITIAL>"void"                         { out.println("VOID"); }
    <YYINITIAL>"return"                       { out.println("RETURN"); }
    <YYINITIAL>"continue"                     { out.println("CONTINUE");}           
    <YYINITIAL>"new"                          { out.println("NEW"); }
    <YYINITIAL>"delete"                       { out.println("DELETE"); }

    <YYINITIAL>"("                            { out.println( "LEFT ARENTHESIS" ); }
    <YYINITIAL>")"                            { out.println( "RIGHT PARENTHESIS" ); }
    <YYINITIAL>"{"                            { out.println( "LEFT CURLY BRACKET" ); }
    <YYINITIAL>"}"                            { out.println( "RIGHT CURLY BRACKET" ); }
    <YYINITIAL>"["                            { out.println( "LEFT SQ" ); }
    <YYINITIAL>"]"                            { out.println( "RIGHT SQ" ); }
    <YYINITIAL>";"                            { out.println( "SEMICOLON" ); }
    <YYINITIAL>","                            { out.println( "COMMA" ); }

    <YYINITIAL> {

    /* identifiers */ 
    {Identifier}                   { out.println("id:" + yytext()); }

    /* literals */
    {IntegerLiteral}               { out.println("integer:" + yytext()); }
    {FloatLiteral}               { out.println("float:" + yytext()); }

    \"                             { sb.setLength(0); yybegin(STRING); }
    \'                             { sb.setLength(0); yybegin(CHAR); }

    /* operators */
    "="                            { out.println("ASSIGN"); }
    "+"                            { out.println("PLUS"); }
    ";"                            { out.println("SEMICOLON"); } 
    ">"                            { out.println("GREATER THAN"); } 
    "<"                            { out.println("LESS THAN"); } 
    "!="                           { out.println("NOT EQUAL TO"); } 
    "<="                           { out.println("LESS OR EQUAL THAN"); } 
    ">="                           { out.println("GREATER OR EQUAL THAN"); } 
    "−"                            { out.println("SUBTRACTION"); } 
    "*"                            { out.println("MULTIPLICATION"); } 
    "/"                            { out.println("DIVISION"); } 
    "%"                            { out.println("PERCENT"); } 
    "=="                           { out.println("EQUALS"); } 
    "&&"                           { out.println("AND"); } 
    "||"                           { out.println("OR"); } 

    /* comments */
    {Comment}                      { /* ignore */ }

    /* whitespace */
    {WhiteSpace}                   { /* ignore */ }
    }

    <STRING> {
    \"                             { yybegin(YYINITIAL);
                                out.println("string:" + sb.toString()); }

    [^\n\r\"\\]+                   { sb.append(yytext()); }
    \\t                            { sb.append('\t'); }
    \\n                            { sb.append('\n'); }


    \\r                            { sb.append('\r'); }
    \\\"                           { sb.append('\"'); }
    \\                             { sb.append('\\'); }
    }

    <CHAR> {
    \'                             { yybegin(YYINITIAL);
                                out.println("char:" + sb.toString()); }

    [^\n\r\0\'\\]+                 { sb.append(yytext()); }
    \\t                            { sb.append('\t'); }
    \\n                            { sb.append('\n'); }
    \\0                            { sb.append('\0'); }                        

    \\r                            { sb.append('\r'); }
    \\\'                           { sb.append('\''); }
    \\                             { sb.append('\\'); }
    }


    /* error fallback */
    [^]                                { throw new RuntimeException((yyline+1) + ":" + (yycolumn+1) + ": illegal character <"+ yytext()+">"); }

1 个答案:

答案 0 :(得分:0)

在尝试之后我找到了一个可以接受的解决方案,我只是在CHAR状态中替换了这段代码:

    var BudgetTable = React.createClass({
        getInitialState : function(){
            return {
                items : this.props.items
            };
        },
        handleCallback : function(idx, n){
            var items = this.state.items;
            items[idx].n = n;
            this.setState({
                items : items
            });
        },
        render : function(){
            console.log(this.state.items[0]);
            return (
                <table className="table monofont">
                    <thead>
                        <tr className="blue">
                            <td className="text-center" colSpan="4">Table</td>
                        </tr>
                    </thead>
                    <tbody>
                        <tr><td colSpan="4">
                            {this.state.items.map((it, idx) =>
                                <BudgetTableButton key={it.label+'r'} label={it.label} idx={idx} callback={this.handleCallback} n={it.n} />
                            )}
                        </td></tr>
                        {this.state.items.map((it, idx) =>
                            <BudgetTableRow key={it.label+'b'} label={it.label} name={it.name} price={it.price} idx={idx} callback={this.handleCallback} n={it.n} />
                        )}
                    </tbody>
                </table>
            );
        }
    });
    function init(){
        return [
            { 
                "price": 1340, 
                "name": "shoe", 
                "label": "Q41",
                "n" : 1
            }, { 
                "price": 1290, 
                "name": "clothes", 
                "label": "Q42",
                "n" : 1
            }
        ];
    }
    ReactDOM.render(
        <BudgetTable items={init()} />,
        document.getElementById("canvas")
    );
    </script>
</body>
</html>

以下内容:

\'                             { yybegin(YYINITIAL);
                            out.println("char:" + sb.toString()); }

希望这可以帮助有类似问题的人